[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
This commit is contained in:
parent
7d1538cd3d
commit
585da50d7d
11
third-party/README.md
vendored
Normal file
11
third-party/README.md
vendored
Normal file
@ -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).
|
||||
26
third-party/boost-math/.codecov.yml
vendored
Normal file
26
third-party/boost-math/.codecov.yml
vendored
Normal file
@ -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/**/*
|
||||
75
third-party/boost-math/.drone.star
vendored
Normal file
75
third-party/boost-math/.drone.star
vendored
Normal file
@ -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': '<cxxflags>-fsanitize=address <linkflags>-fsanitize=address <cxxflags>-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': '<cxxflags>-fsanitize=undefined <linkflags>-fsanitize=undefined <cxxflags>-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': '<cxxflags>-fsanitize=thread <linkflags>-fsanitize=thread <cxxflags>-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': '<cxxflags>-fsanitize=integer <linkflags>-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")
|
||||
96
third-party/boost-math/.gitattributes
vendored
Normal file
96
third-party/boost-math/.gitattributes
vendored
Normal file
@ -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
|
||||
30
third-party/boost-math/.gitignore
vendored
Normal file
30
third-party/boost-math/.gitignore
vendored
Normal file
@ -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
|
||||
795
third-party/boost-math/.travis.yml
vendored
Normal file
795
third-party/boost-math/.travis.yml
vendored
Normal file
@ -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 : <cxxflags>-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
|
||||
61
third-party/boost-math/CMakeLists.txt
vendored
Normal file
61
third-party/boost-math/CMakeLists.txt
vendored
Normal file
@ -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()
|
||||
23
third-party/boost-math/LICENSE
vendored
Normal file
23
third-party/boost-math/LICENSE
vendored
Normal file
@ -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.
|
||||
180
third-party/boost-math/README.md
vendored
Normal file
180
third-party/boost-math/README.md
vendored
Normal file
@ -0,0 +1,180 @@
|
||||
Boost Math Library
|
||||
============================
|
||||
|
||||
>ANNOUNCEMENT: This library requires a compliant C++14 compiler.
|
||||
|
||||
|
||||
| | Master | Develop |
|
||||
|------------------|----------|-------------|
|
||||
| Drone | [](https://drone.cpp.al/boostorg/math) | [](https://drone.cpp.al/boostorg/math) |
|
||||
| Github Actions | [](https://github.com/boostorg/math/actions?query=branch%3Amaster) | [](https://github.com/boostorg/math/actions?query=branch%3Adevelop) |
|
||||
| Codecov | [](https://codecov.io/gh/boostorg/math/branch/master) | [](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 `<stdfloat>` 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
|
||||
```
|
||||
48
third-party/boost-math/build.jam
vendored
Normal file
48
third-party/boost-math/build.jam
vendored
Normal file
@ -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>include
|
||||
;
|
||||
|
||||
explicit
|
||||
[ alias boost_math : : : : <library>$(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 : : : :
|
||||
<include>test
|
||||
<include>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
|
||||
;
|
||||
|
||||
58
third-party/boost-math/include/boost/cstdfloat.hpp
vendored
Normal file
58
third-party/boost-math/include/boost/cstdfloat.hpp
vendored
Normal file
@ -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)
|
||||
//
|
||||
|
||||
// <boost/cstdfloat.hpp> 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 <boost/math/cstdfloat/cstdfloat_types.hpp>
|
||||
|
||||
// Support a specialization of std::numeric_limits<> for the wrapped quadmath library (if available).
|
||||
#if !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS)
|
||||
#include <boost/math/cstdfloat/cstdfloat_limits.hpp>
|
||||
#endif
|
||||
|
||||
// Support <cmath> functions for the wrapped quadmath library (if available).
|
||||
#if !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH)
|
||||
#include <boost/math/cstdfloat/cstdfloat_cmath.hpp>
|
||||
#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 <boost/math/cstdfloat/cstdfloat_iostream.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined.
|
||||
#endif
|
||||
#include <boost/math/cstdfloat/cstdfloat_iostream.hpp>
|
||||
#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 <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS defined.
|
||||
#endif
|
||||
#if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH)
|
||||
#error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined.
|
||||
#endif
|
||||
#if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM)
|
||||
#error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM defined.
|
||||
#endif
|
||||
#include <boost/math/cstdfloat/cstdfloat_complex.hpp>
|
||||
#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_
|
||||
297
third-party/boost-math/include/boost/math/bindings/detail/big_digamma.hpp
vendored
Normal file
297
third-party/boost-math/include/boost/math/bindings/detail/big_digamma.hpp
vendored
Normal file
@ -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 <boost/math/tools/rational.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/tools/big_constant.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class T>
|
||||
T big_digamma_helper(T x)
|
||||
{
|
||||
static const T P[61] = {
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6660133691143982067148122682345055274952e81),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6365271516829242456324234577164675383137e81),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2991038873096202943405966144203628966976e81),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.9211116495503170498076013367421231351115e80),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2090792764676090716286400360584443891749e80),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3730037777359591428226035156377978092809e79),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5446396536956682043376492370432031543834e78),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6692523966335177847425047827449069256345e77),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.7062543624100864681625612653756619116848e76),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6499914905966283735005256964443226879158e75),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5280364564853225211197557708655426736091e74),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3823205608981176913075543599005095206953e73),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2486733714214237704739129972671154532415e72),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1462562139602039577983434547171318011675e71),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.7821169065036815012381267259559910324285e69),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3820552182348155468636157988764435365078e68),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1711618296983598244658239925535632505062e67),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.7056661618357643731419080738521475204245e65),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2685246896473614017356264531791459936036e64),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.9455168125599643085283071944864977592391e62),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3087541626972538362237309145177486236219e61),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.9367928873352980208052601301625005737407e59),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2645306130689794942883818547314327466007e58),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6961815141171454309161007351079576190079e56),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1709637824471794552313802669803885946843e55),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3921553258481531526663112728778759311158e53),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.8409006354449988687714450897575728228696e51),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1686755204461325935742097669030363344927e50),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3166653542877070999007425197729038754254e48),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5566029092358215049069560272835654229637e46),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.9161766287916328133080586672953875116242e44),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1412317772330871298317974693514430627922000),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 20387991986727877473732570146112459874790),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 275557928713904105182512535678580359839.3),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 3485719851040516559072031256589598330.723),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 41247046743564028399938106707656877.40859),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 456274078125709314602601667471879.0147312),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 4714450683242899367025707077155.310613012),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 45453933537925041680009544258.75073849996),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 408437900487067278846361972.302331241052),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 3415719344386166273085838.705771571751035),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 26541502879185876562320.93134691487351145),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 191261415065918713661.1571433274648417668),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1275349770108718421.645275944284937551702),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 7849171120971773.318910987434906905704272),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 44455946386549.80866460312682983576538056),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 230920362395.3198137186361608905136598046),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1095700096.240863858624279930600654130254),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 4727085.467506050153744334085516289728134),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 18440.75118859447173303252421991479005424),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 64.62515887799460295677071749181651317052),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.201851568864688406206528472883512147547),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.0005565091674187978029138500039504078098143),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1338097668312907986354698683493366559613e-5),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.276308225077464312820179030238305271638e-8),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.4801582970473168520375942100071070575043e-11),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6829184144212920949740376186058541800175e-14),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.7634080076358511276617829524639455399182e-17),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6290035083727140966418512608156646142409e-20),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.339652245667538733044036638506893821352e-23),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.9017518064256388530773585529891677854909e-27)
|
||||
};
|
||||
static const T Q[61] = {
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1386831185456898357379390197203894063459e81),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6467076379487574703291056110838151259438e81),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1394967823848615838336194279565285465161e82),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1872927317344192945218570366455046340458e82),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1772461045338946243584650759986310355937e82),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1267294892200258648315971144069595555118e82),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.7157764838362416821508872117623058626589e81),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.329447266909948668265277828268378274513e81),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1264376077317689779509250183194342571207e81),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.4118230304191980787640446056583623228873e80),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1154393529762694616405952270558316515261e80),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.281655612889423906125295485693696744275e79),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6037483524928743102724159846414025482077e78),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1145927995397835468123576831800276999614e78),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1938624296151985600348534009382865995154e77),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.293980925856227626211879961219188406675e76),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.4015574518216966910319562902099567437832e75),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.4961475457509727343545565970423431880907e74),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5565482348278933960215521991000378896338e73),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5686112924615820754631098622770303094938e72),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5305988545844796293285410303747469932856e71),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.4533363413802585060568537458067343491358e70),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3553932059473516064068322757331575565718e69),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2561198565218704414618802902533972354203e68),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1699519313292900324098102065697454295572e67),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1039830160862334505389615281373574959236e66),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5873082967977428281000961954715372504986e64),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3065255179030575882202133042549783442446e63),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1479494813481364701208655943688307245459e62),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6608150467921598615495180659808895663164e60),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2732535313770902021791888953487787496976e59),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1046402297662493314531194338414508049069e58),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3711375077192882936085049147920021549622e56),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1219154482883895482637944309702972234576e55),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3708359374149458741391374452286837880162e53),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1044095509971707189716913168889769471468e52),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.271951506225063286130946773813524945052e50),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6548016291215163843464133978454065823866e48),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1456062447610542135403751730809295219344e47),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2986690175077969760978388356833006028929e45),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 5643149706574013350061247429006443326844000),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 98047545414467090421964387960743688053480),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1563378767746846395507385099301468978550),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 22823360528584500077862274918382796495),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 304215527004115213046601295970388750),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 3690289075895685793844344966820325),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 40584512015702371433911456606050),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 402834190897282802772754873905),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 3589522158493606918146495750),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 28530557707503483723634725),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 200714561335055753000730),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1237953783437761888641),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 6614698701445762950),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 30155495647727505),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 114953256021450),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 356398020013),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 863113950),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1531345),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1770),
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1)
|
||||
};
|
||||
static const T PD[60] = {
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6365271516829242456324234577164675383137e81),
|
||||
2*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2991038873096202943405966144203628966976e81),
|
||||
3*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.9211116495503170498076013367421231351115e80),
|
||||
4*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2090792764676090716286400360584443891749e80),
|
||||
5*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3730037777359591428226035156377978092809e79),
|
||||
6*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5446396536956682043376492370432031543834e78),
|
||||
7*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6692523966335177847425047827449069256345e77),
|
||||
8*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.7062543624100864681625612653756619116848e76),
|
||||
9*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6499914905966283735005256964443226879158e75),
|
||||
10*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5280364564853225211197557708655426736091e74),
|
||||
11*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3823205608981176913075543599005095206953e73),
|
||||
12*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2486733714214237704739129972671154532415e72),
|
||||
13*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1462562139602039577983434547171318011675e71),
|
||||
14*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.7821169065036815012381267259559910324285e69),
|
||||
15*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3820552182348155468636157988764435365078e68),
|
||||
16*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1711618296983598244658239925535632505062e67),
|
||||
17*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.7056661618357643731419080738521475204245e65),
|
||||
18*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2685246896473614017356264531791459936036e64),
|
||||
19*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.9455168125599643085283071944864977592391e62),
|
||||
20*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3087541626972538362237309145177486236219e61),
|
||||
21*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.9367928873352980208052601301625005737407e59),
|
||||
22*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2645306130689794942883818547314327466007e58),
|
||||
23*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6961815141171454309161007351079576190079e56),
|
||||
24*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1709637824471794552313802669803885946843e55),
|
||||
25*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3921553258481531526663112728778759311158e53),
|
||||
26*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.8409006354449988687714450897575728228696e51),
|
||||
27*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1686755204461325935742097669030363344927e50),
|
||||
28*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3166653542877070999007425197729038754254e48),
|
||||
29*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5566029092358215049069560272835654229637e46),
|
||||
30*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.9161766287916328133080586672953875116242e44),
|
||||
31*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1412317772330871298317974693514430627922000),
|
||||
32*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 20387991986727877473732570146112459874790),
|
||||
33*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 275557928713904105182512535678580359839.3),
|
||||
34*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 3485719851040516559072031256589598330.723),
|
||||
35*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 41247046743564028399938106707656877.40859),
|
||||
36*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 456274078125709314602601667471879.0147312),
|
||||
37*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 4714450683242899367025707077155.310613012),
|
||||
38*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 45453933537925041680009544258.75073849996),
|
||||
39*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 408437900487067278846361972.302331241052),
|
||||
40*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 3415719344386166273085838.705771571751035),
|
||||
41*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 26541502879185876562320.93134691487351145),
|
||||
42*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 191261415065918713661.1571433274648417668),
|
||||
43*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1275349770108718421.645275944284937551702),
|
||||
44*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 7849171120971773.318910987434906905704272),
|
||||
45*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 44455946386549.80866460312682983576538056),
|
||||
46*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 230920362395.3198137186361608905136598046),
|
||||
47*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1095700096.240863858624279930600654130254),
|
||||
48*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 4727085.467506050153744334085516289728134),
|
||||
49*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 18440.75118859447173303252421991479005424),
|
||||
50*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 64.62515887799460295677071749181651317052),
|
||||
51*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.201851568864688406206528472883512147547),
|
||||
52*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.0005565091674187978029138500039504078098143),
|
||||
53*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1338097668312907986354698683493366559613e-5),
|
||||
54*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.276308225077464312820179030238305271638e-8),
|
||||
55*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.4801582970473168520375942100071070575043e-11),
|
||||
56*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6829184144212920949740376186058541800175e-14),
|
||||
57*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.7634080076358511276617829524639455399182e-17),
|
||||
58*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6290035083727140966418512608156646142409e-20),
|
||||
59*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.339652245667538733044036638506893821352e-23),
|
||||
60*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.9017518064256388530773585529891677854909e-27)
|
||||
};
|
||||
static const T QD[60] = {
|
||||
BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1386831185456898357379390197203894063459e81),
|
||||
2*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6467076379487574703291056110838151259438e81),
|
||||
3*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1394967823848615838336194279565285465161e82),
|
||||
4*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1872927317344192945218570366455046340458e82),
|
||||
5*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1772461045338946243584650759986310355937e82),
|
||||
6*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1267294892200258648315971144069595555118e82),
|
||||
7*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.7157764838362416821508872117623058626589e81),
|
||||
8*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.329447266909948668265277828268378274513e81),
|
||||
9*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1264376077317689779509250183194342571207e81),
|
||||
10*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.4118230304191980787640446056583623228873e80),
|
||||
11*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1154393529762694616405952270558316515261e80),
|
||||
12*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.281655612889423906125295485693696744275e79),
|
||||
13*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6037483524928743102724159846414025482077e78),
|
||||
14*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1145927995397835468123576831800276999614e78),
|
||||
15*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1938624296151985600348534009382865995154e77),
|
||||
16*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.293980925856227626211879961219188406675e76),
|
||||
17*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.4015574518216966910319562902099567437832e75),
|
||||
18*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.4961475457509727343545565970423431880907e74),
|
||||
19*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5565482348278933960215521991000378896338e73),
|
||||
20*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5686112924615820754631098622770303094938e72),
|
||||
21*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5305988545844796293285410303747469932856e71),
|
||||
22*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.4533363413802585060568537458067343491358e70),
|
||||
23*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3553932059473516064068322757331575565718e69),
|
||||
24*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2561198565218704414618802902533972354203e68),
|
||||
25*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1699519313292900324098102065697454295572e67),
|
||||
26*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1039830160862334505389615281373574959236e66),
|
||||
27*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.5873082967977428281000961954715372504986e64),
|
||||
28*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3065255179030575882202133042549783442446e63),
|
||||
29*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1479494813481364701208655943688307245459e62),
|
||||
30*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6608150467921598615495180659808895663164e60),
|
||||
31*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2732535313770902021791888953487787496976e59),
|
||||
32*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1046402297662493314531194338414508049069e58),
|
||||
33*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3711375077192882936085049147920021549622e56),
|
||||
34*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1219154482883895482637944309702972234576e55),
|
||||
35*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.3708359374149458741391374452286837880162e53),
|
||||
36*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1044095509971707189716913168889769471468e52),
|
||||
37*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.271951506225063286130946773813524945052e50),
|
||||
38*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.6548016291215163843464133978454065823866e48),
|
||||
39*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.1456062447610542135403751730809295219344e47),
|
||||
40*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 0.2986690175077969760978388356833006028929e45),
|
||||
41*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 5643149706574013350061247429006443326844000),
|
||||
42*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 98047545414467090421964387960743688053480),
|
||||
43*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1563378767746846395507385099301468978550),
|
||||
44*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 22823360528584500077862274918382796495),
|
||||
45*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 304215527004115213046601295970388750),
|
||||
46*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 3690289075895685793844344966820325),
|
||||
47*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 40584512015702371433911456606050),
|
||||
48*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 402834190897282802772754873905),
|
||||
49*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 3589522158493606918146495750),
|
||||
50*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 28530557707503483723634725),
|
||||
51*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 200714561335055753000730),
|
||||
52*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1237953783437761888641),
|
||||
53*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 6614698701445762950),
|
||||
54*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 30155495647727505),
|
||||
55*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 114953256021450),
|
||||
56*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 356398020013),
|
||||
57*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 863113950),
|
||||
58*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1531345),
|
||||
59*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::digits, 1770),
|
||||
60*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits<T>::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 <class T>
|
||||
T big_digamma(T x)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
|
||||
if(x < 0)
|
||||
{
|
||||
return big_digamma_helper(static_cast<T>(1-x)) + constants::pi<T>() / tan(constants::pi<T>() * (1-x));
|
||||
}
|
||||
return big_digamma_helper(x);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif // include guard
|
||||
777
third-party/boost-math/include/boost/math/bindings/detail/big_lanczos.hpp
vendored
Normal file
777
third-party/boost-math/include/boost/math/bindings/detail/big_lanczos.hpp
vendored
Normal file
@ -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 <boost/math/special_functions/lanczos.hpp>
|
||||
|
||||
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<int, 120>
|
||||
{
|
||||
//
|
||||
// Produces slightly better than 128-bit long-double precision when
|
||||
// evaluated at higher precision:
|
||||
//
|
||||
template <class T>
|
||||
static T lanczos_sum(const T& z)
|
||||
{
|
||||
lanczos_initializer<lanczos22UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
static const T num[22] = {
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 46198410803245094237463011094.12173081986)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 43735859291852324413622037436.321513777)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 19716607234435171720534556386.97481377748)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 5629401471315018442177955161.245623932129)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1142024910634417138386281569.245580222392)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 175048529315951173131586747.695329230778)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 21044290245653709191654675.41581372963167)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2033001410561031998451380.335553678782601)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 160394318862140953773928.8736211601848891)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 10444944438396359705707.48957290388740896)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 565075825801617290121.1466393747967538948)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 25475874292116227538.99448534450411942597)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 957135055846602154.6720835535232270205725)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 29874506304047462.23662392445173880821515)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 769651310384737.2749087590725764959689181)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 16193289100889.15989633624378404096011797)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 273781151680.6807433264462376754578933261)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3630485900.32917021712188739762161583295)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 36374352.05577334277856865691538582936484)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 258945.7742115532455441786924971194951043)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1167.501919472435718934219997431551246996)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2.50662827463100050241576528481104525333))
|
||||
};
|
||||
static const T denom[22] = {
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2432902008176640000.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 8752948036761600000.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 13803759753640704000.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 12870931245150988800.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 8037811822645051776.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3599979517947607200.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1206647803780373360.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 311333643161390640.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 63030812099294896.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 10142299865511450.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1307535010540395.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 135585182899530.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 11310276995381.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 756111184500.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 40171771630.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1672280820.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 53327946.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1256850.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 20615.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 210.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1.0))
|
||||
};
|
||||
return boost::math::tools::evaluate_rational(num, denom, z);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static T lanczos_sum_expG_scaled(const T& z)
|
||||
{
|
||||
lanczos_initializer<lanczos22UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
static const T num[22] = {
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 6939996264376682180.277485395074954356211)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 6570067992110214451.87201438870245659384)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2961859037444440551.986724631496417064121)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 845657339772791245.3541226499766163431651)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 171556737035449095.2475716923888737881837)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 26296059072490867.7822441885603400926007)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3161305619652108.433798300149816829198706)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 305400596026022.4774396904484542582526472)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 24094681058862.55120507202622377623528108)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1569055604375.919477574824168939428328839)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 84886558909.02047889339710230696942513159)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3827024985.166751989686050643579753162298)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 143782298.9273215199098728674282885500522)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 4487794.24541641841336786238909171265944)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 115618.2025760830513505888216285273541959)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2432.580773108508276957461757328744780439)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 41.12782532742893597168530008461874360191)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.5453771709477689805460179187388702295792)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.005464211062612080347167337964166505282809)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.388992321263586767037090706042788910953e-4)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.1753839324538447655939518484052327068859e-6)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.3765495513732730583386223384116545391759e-9))
|
||||
};
|
||||
static const T denom[22] = {
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 2432902008176640000.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 8752948036761600000.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 13803759753640704000.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 12870931245150988800.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 8037811822645051776.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3599979517947607200.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1206647803780373360.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 311333643161390640.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 63030812099294896.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 10142299865511450.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1307535010540395.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 135585182899530.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 11310276995381.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 756111184500.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 40171771630.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1672280820.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 53327946.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1256850.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 20615.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 210.0)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1.0))
|
||||
};
|
||||
return boost::math::tools::evaluate_rational(num, denom, z);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
static T lanczos_sum_near_1(const T& dz)
|
||||
{
|
||||
lanczos_initializer<lanczos22UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
static const T d[21] = {
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 8.318998691953337183034781139546384476554)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -63.15415991415959158214140353299240638675)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 217.3108224383632868591462242669081540163)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -448.5134281386108366899784093610397354889)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 619.2903759363285456927248474593012711346)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -604.1630177420625418522025080080444177046)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 428.8166750424646119935047118287362193314)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -224.6988753721310913866347429589434550302)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 87.32181627555510833499451817622786940961)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -25.07866854821128965662498003029199058098)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 5.264398125689025351448861011657789005392)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.792518936256495243383586076579921559914)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.08317448364744713773350272460937904691566)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.005845345166274053157781068150827567998882)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0002599412126352082483326238522490030412391)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.6748102079670763884917431338234783496303e-5)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.908824383434109002762325095643458603605e-7)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.5299325929309389890892469299969669579725e-9)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.994306085859549890267983602248532869362e-12)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.3499893692975262747371544905820891835298e-15)),
|
||||
static_cast<T>(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<class T>
|
||||
static T lanczos_sum_near_2(const T& dz)
|
||||
{
|
||||
static const T d[21] = {
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 75.39272007105208086018421070699575462226)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -572.3481967049935412452681346759966390319)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 1969.426202741555335078065370698955484358)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -4064.74968778032030891520063865996757519)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 5612.452614138013929794736248384309574814)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -5475.357667500026172903620177988213902339)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 3886.243614216111328329547926490398103492)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -2036.382026072125407192448069428134470564)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 791.3727954936062108045551843636692287652)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -227.2808432388436552794021219198885223122)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 47.70974355562144229897637024320739257284)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -7.182373807798293545187073539819697141572)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.7537866989631514559601547530490976100468)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.05297470142240154822658739758236594717787)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.00235577330936380542539812701472320434133)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.6115613067659273118098229498679502138802e-4)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.8236417010170941915758315020695551724181e-6)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.4802628430993048190311242611330072198089e-8)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, 0.9011113376981524418952720279739624707342e-11)),
|
||||
static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 120, -0.3171854152689711198382455703658589996796e-14)),
|
||||
static_cast<T>(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 <class T>
|
||||
static T lanczos_sum(const T& z)
|
||||
{
|
||||
lanczos_initializer<lanczos31UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
static const T num[31] = {
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2579646553333513328235723061836959833277e46)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2444796504337453845497419271639377138264e46)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1119885499016017172212179730662673475329e46)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3301983829072723658949204487793889113715e45)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.7041171040503851585152895336505379417066e44)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1156687509001223855125097826246939403504e44)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1522559363393940883866575697565974893306000)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 164914363507650839510801418717701057005700)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 14978522943127593263654178827041568394060)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1156707153701375383907746879648168666774)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 76739431129980851159755403434593664173.2)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4407916278928188620282281495575981079.306)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 220487883931812802092792125175269667.3004)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 9644828280794966468052381443992828.433924)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 369996467042247229310044531282837.6549068)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 12468380890717344610932904378961.13494291)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 369289245210898235894444657859.0529720075)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 9607992460262594951559461829.34885209022)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 219225935074853412540086410.981421315799)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4374309943598658046326340.720767382079549)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 76008779092264509404014.10530947173485581)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1143503533822162444712.335663112617754987)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 14779233719977576920.37884890049671578409)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 162409028440678302.9992838032166348069916)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1496561553388385.733407609544964535634135)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 11347624460661.81008311053190661436107043)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 68944915931.32004991941950530448472223832)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 322701221.6391432296123937035480931903651)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1092364.213992634267819050120261755371294)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2380.151399852411512711176940867823024864)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2.506628274631000502415765284811045253007)),
|
||||
};
|
||||
static const T denom[31] = {
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.8841761993739701954543616e31)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3502799997985980526649278464e32)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.622621928420356134910574592e32)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 66951000306085302338993639424000)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 49361465831621147825759587123200)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 26751280755793398822580822142976)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 11139316913434780466101123891200)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 3674201658710345201899117607040)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 981347603630155088295475765440)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 215760462268683520394805979744)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 39539238727270799376544542000)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 6097272817323042122728617800)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 796974693974455191377937300)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 88776380550648116217781890)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 8459574446076318147830625)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 691254538651580660999025)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 48487623689430693038025)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2918939500751087661105)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 150566737512021319125)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 6634460278534540725)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 248526574856284725)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 7860403394108265)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 207912996295875)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4539323721075)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 80328850875)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1122686019)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 11921175)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 90335)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 435)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1)),
|
||||
};
|
||||
return boost::math::tools::evaluate_rational(num, denom, z, 31);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static T lanczos_sum_expG_scaled(const T& z)
|
||||
{
|
||||
lanczos_initializer<lanczos31UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
static const T num[31] = {
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 30137154810677525966583148469478.52374216)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 28561746428637727032849890123131.36314653)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 13083250730789213354063781611435.74046294)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 3857598154697777600846539129354.783647)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 822596651552555685068015316144.0952185852)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 135131964033213842052904200372.039133532)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 17787555889683709693655685146.19771358863)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1926639793777927562221423874.149673297196)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 174989113988888477076973808.6991839697774)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 13513425905835560387095425.01158383184045)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 896521313378762433091075.1446749283094845)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 51496223433749515758124.71524415105430686)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2575886794780078381228.37205955912263407)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 112677328855422964200.4155776009524490958)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4322545967487943330.625233358130724324796)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 145663957202380774.0362027607207590519723)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4314283729473470.686566233465428332496534)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 112246988185485.8877916434026906290603878)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2561143864972.040563435178307062626388193)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 51103611767.9626550674442537989885239605)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 887985348.0369447209508500133077232094491)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 13359172.3954672607019822025834072685839)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 172660.8841147568768783928167105965064459)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1897.370795407433013556725714874693719617)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 17.48383210090980598861217644749573257178)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1325705316732132940835251054350153028901)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0008054605783673449641889260501816356090452)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.377001130700104515644336869896819162464e-5)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1276172868883867038813825443204454996531e-7)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2780651912081116274907381023821492811093e-10)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2928410648650955854121639682890739211234e-13)),
|
||||
};
|
||||
static const T denom[31] = {
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.8841761993739701954543616e31)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3502799997985980526649278464e32)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.622621928420356134910574592e32)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 66951000306085302338993639424000)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 49361465831621147825759587123200)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 26751280755793398822580822142976)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 11139316913434780466101123891200)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 3674201658710345201899117607040)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 981347603630155088295475765440)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 215760462268683520394805979744)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 39539238727270799376544542000)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 6097272817323042122728617800)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 796974693974455191377937300)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 88776380550648116217781890)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 8459574446076318147830625)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 691254538651580660999025)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 48487623689430693038025)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2918939500751087661105)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 150566737512021319125)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 6634460278534540725)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 248526574856284725)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 7860403394108265)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 207912996295875)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4539323721075)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 80328850875)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1122686019)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 11921175)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 90335)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 435)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1)),
|
||||
};
|
||||
return boost::math::tools::evaluate_rational(num, denom, z, 31);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
static T lanczos_sum_near_1(const T& dz)
|
||||
{
|
||||
lanczos_initializer<lanczos31UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
static const T d[30] = {
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 11.80038544942943603508206880307972596807)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -130.6355975335626214564236363322099481079)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 676.2177719145993049893392276809256538927)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -2174.724497783850503069990936574060452057)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4869.877180638131076410069103742986502022)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -8065.744271864238179992762265472478229172)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 10245.03825618572106228191509520638651539)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -10212.83902362683215459850403668669647192)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 8110.289185383288952562767679576754140336)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -5179.310892558291062401828964000776095156)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2673.987492589052370230989109591011091273)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1118.342574651205183051884250033505609141)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 378.5812742511620662650096436471920295596)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -103.3725999812126067084828735543906768961)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 22.62913974335996321848099677797888917792)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -3.936414819950859548507275533569588041446)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.5376818198843817355682124535902641644854)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.0567827903603478957483409124122554243201)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.004545544993648879420352693271088478106482)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.0002689795568951033950042375135970897959935)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1139493459006846530734617710847103572122e-4)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.3316581197839213921885210451302820192794e-6)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.6285613334898374028443777562554713906213e-8)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.7222145115734409070310317999856424167091e-10)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.4562976983547274766890241815002584238219e-12)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1380593023819058919640038942493212141072e-14)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1629663871586410129307496385264268190679e-17)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.5429994291916548849493889660077076739993e-21)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2922682842441892106795386303084661338957e-25)),
|
||||
static_cast<T>(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<class T>
|
||||
static T lanczos_sum_near_2(const T& dz)
|
||||
{
|
||||
lanczos_initializer<lanczos31UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
static const T d[30] = {
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 147.9979641587472136175636384176549713358)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1638.404318611773924210055619836375434296)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 8480.981744216135641122944743711911653273)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -27274.93942104458448200467097634494071176)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 61076.98019918759324489193232276937262854)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -101158.8762737154296509560513952101409264)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 128491.1252383947174824913796141607174379)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -128087.2892038336581928787480535905496026)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 101717.5492545853663296795562084430123258)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -64957.8330410311808907869707511362206858)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 33536.59139229792478811870738772305570317)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -14026.01847115365926835980820243003785821)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4748.087094096186515212209389240715050212)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1296.477510211815971152205100242259733245)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 283.8099337545793198947620951499958085157)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -49.36969067101255103452092297769364837753)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 6.743492833270653628580811118017061581404)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.7121578704864048548351804794951487823626)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0570092738016915476694118877057948681298)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.003373485297696102660302960722607722438643)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0001429128843527532859999752593761934089751)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.41595867130858508233493767243236888636e-5)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.7883284669307241040059778207492255409785e-7)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.905786322462384670803148223703187214379e-9)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.5722790216999820323272452464661250331451e-11)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1731510870832349779315841757234562309727e-13)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2043890314358438601429048378015983874378e-16)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.6810185176079344204740000170500311171065e-20)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3665567641131713928114853776588342403919e-24)),
|
||||
static_cast<T>(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 <class T>
|
||||
static T lanczos_sum(const T& z)
|
||||
{
|
||||
lanczos_initializer<lanczos61UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
using namespace boost;
|
||||
static const T d[61] = {
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2.50662827463100050241576528481104525300698674060993831662992357634229365460784197494659584)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 13349415823254323512107320481.3495396037261649201426994438803767191136434970492309775123879)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -300542621510568204264185787475.230003734889859348050696493467253861933279360152095861484548)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 3273919938390136737194044982676.40271056035622723775417608127544182097346526115858803376474)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -22989594065095806099337396006399.5874206181563663855129141706748733174902067950115092492439)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 116970582893952893160414263796102.542775878583510989850142808618916073286745084692189044738)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -459561969036479455224850813196807.283291532483532558959779434457349912822256480548436066098)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1450959909778264914956547227964788.89797179379520834974601372820249784303794436366366810477)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -3782846865486775046285288437885921.41537699732805465141128848354901016102326190612528503251)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 8305043213936355459145388670886540.09976337905520168067329932809302445437208115570138102767)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -15580988484396722546934484726970745.4927787160273626078250810989811865283255762028143642311)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 25262722284076250779006793435537600.0822901485517345545978818780090308947301031347345640449)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -35714428027687018805443603728757116.5304655170478705341887572982734901197345415291580897698)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 44334726194692443174715432419157343.2294160783772787096321009453791271387235388689346602833)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -48599573547617297831555162417695106.187829304963846482633791012658974681648157963911491985)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 47258466493366798944386359199482189.0753349196625125615316002614813737880755896979754845101)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -40913448215392412059728312039233342.142914753896559359297977982314043378636755884088383226)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 31626312914486892948769164616982902.7262756989418188077611392594232674722318027323102462687)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -21878079174441332123064991795834438.4699982361692990285700077902601657354101259411789722708)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 13567268503974326527361474986354265.3136632133935430378937191911532112778452274286122946396)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -7551494211746723529747611556474669.62996644923557605747803028485900789337467673523741066527)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 3775516572689476384052312341432597.70584966904950490541958869730702790312581801585742038997)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1696271471453637244930364711513292.79902955514107737992185368006225264329876265486853482449)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 684857608019352767999083000986166.20765273693720041519286231015176745354062413008561259139)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -248397566275708464679881624417990.410438107634139924805871051723444048539177890346227250473)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 80880368999557992138783568858556.1512378233079327986518410244522800950609595592170022878937)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -23618197945394013802495450485616.9025005749893350650829964098117490779655546610665927669729)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 6176884636893816103087134481332.06708966653493024119556843727320635285468825056891248447124)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1444348683723439589948246285262.64080678953468490544615312565485170860503207005915261691108)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 301342031656979076702313946827.961658905182634508217626783081241074250132289461989777865387)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -55959656587719766738301589651.3940625826610668990368881615587469329021742236397809951765678)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 9223339169004064297247180402.36227016155682738556103138196079389248843082157924368301293963)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1344882881571942601385730283.42710150182526891377514071881534880944872423492272147871101373)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 172841913316760599352601139.54409257740173055624405575900164401527761357324625574736896079)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -19496120443876233531343952.3802212016691702737346568192063937387825469602063310488794471653)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1920907372583710284097959.44121420322495784420169085871802458519363819782779653621724219067)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -164429314798240461613359.399597503536657962383155875723527581699785846599051112719962464604)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 12154026644351189572525.1452249886865981747374191977801688548318519692423556934568426042152)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -770443988366210815096.519382051977221101156336663806705367929328924137169970381042234329058)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 41558909851418707920.4696085656889424895313728719601503526476333404973280596225722152966128)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1890879946549708819.24562220042687554209318172044783707920086716716717574156283898330017796)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 71844996557297623.9583461685535340440524052492427928388171299145330229958643439878608673403)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -2253785109518255.55600197759875781765803818232939130127735487613049577235879610065545755637)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 57616883849355.997562563968344493719962252675875692642406455612671495250543228005045106721)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1182495730353.08218118278997948852215670614084013289033222774171548915344541249351599628436)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 19148649358.6196967288062261380599423925174178776792840639099120170800869284300966978300613)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -239779605.891370259668403359614360511661030470269478602533200704639655585967442891496784613)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2267583.00284368310957842936892685032434505866445291643236133553754152047677944820353796872)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -15749.490806784673108773558070497383604733010677027764233749920147549999361110299643477893)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 77.7059495149052727171505425584459982871343274332635726864135949842508025564999785370162956)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.261619987273930331397625130282851629108569607193781378836014468617185550622160348688297247)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.000572252321659691600529444769356185993188551770817110673186068921175991328434642504616377475)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.765167220661540041663007112207436426423746402583423562585653954743978584117929356523307954e-6)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.579179571056209077507916813937971472839851499147582627425979879366849876944438724610663401e-9)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.224804733043915149719206760378355636826808754704148660354494460792713189958510735070096991e-12)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.392711975389579343321746945135488409914483448652884894759297584020979857734289645857714768e-16)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.258603588346412049542768766878162221817684639789901440429511261589010049357907537684380983e-20)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.499992460848751668441190360024540741752242879565548017176883304716370989218399797418478685e-25)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.196211614533318174187346267877390498735734213905206562766348625767919122511096089367364025e-30)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.874722648949676363732094858062907290148733370978226751462386623191111439121706262759209573e-37)),
|
||||
static_cast<T>(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 <class T>
|
||||
static T lanczos_sum_expG_scaled(const T& z)
|
||||
{
|
||||
lanczos_initializer<lanczos61UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
using namespace boost;
|
||||
static const T d[61] = {
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.901751806425638853077358552989167785490911341809902155556127108480303870921448984935411583e-27)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4.80241125306810017699523302110401965428995345115391817406006361151407344955277298373661032)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -108.119283021710869401330097315436214587270846871451487282117128515476478251641970487922552)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1177.78262074811362219818923738088833932279000985161077740440010901595132448469513438139561)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -8270.43570321334374279057432173814835581983913167617217749736484999327758232081395983082867)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 42079.807161997077661752306902088979258826568702655699995911391774839958572703348502730394)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -165326.003834443330215001219988296482004968548294447320869281647211603153902436231468280089)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 521978.361504895300685499370463597042533432134369277742485307843747923127933979566742421213)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1360867.51629992863544553419296636395576666570468519805449755596254912681418267100657262281)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2987713.73338656161102517003716335104823650191612448011720936412226357385029800040631754755)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -5605212.64915921452169919008770165304171481697939254152852673009005154549681704553438450709)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 9088186.58332916818449459635132673652700922052988327069535513580836143146727832380184335474)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -12848155.5543636394746355365819800465364996596310467415907815393346205151090486190421959769)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 15949281.2867656960575878805158849857756293807220033618942867694361569866468996967761600898)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -17483546.9948295433308250581770557182576171673272450149400973735206019559576269174369907171)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 17001087.8599749419660906448951424280111036786456594738278573653160553115681287326064596964)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -14718487.0643665950346574802384331125115747311674609017568623694516187494204567579595827859)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 11377468.7255609717716845971105161298889777425898291183866813269222281486121330837791392732)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -7870571.64253038587947746661946939286858490057774448573157856145556080330153403858747655263)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4880783.08440908743641723492059912671377140680710345996273343885045364205895751515063844239)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -2716626.7992639625103140035635916455652302249897918893040695025407382316653674141983775542)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1358230.46602865696544327299659410214201327791319846880787515156343361311278133805428800255)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -610228.440751458395860905749312275043435828322076830117123636938979942213530882048883969802)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 246375.416501158654327780901087115642493055617468601787093268312234390446439555559050129729)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -89360.2599028475206119333931211015869139511677735549267100272095432140508089207221096740632)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 29096.4637987498328341260960356772198979319790332957125131055960448759586930781530063775634)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -8496.57401431514433694413130585404918350686834939156759654375188338156288564260152505382438)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2222.11523574301594407443285016240908726891841242444092960094015874546135316534057865883047)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -519.599993280949289705514822058693289933461756514489674453254304308040888101533569480646682)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 108.406868361306987817730701109400305482972790224573776407166683184990131682003417239181112)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -20.1313142142558596796857948064047373605439974799116521459977609253211918146595346493447238)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 3.31806787671783168020012913552384112429614503798293169239082032849759155847394955909684383)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.483817477111537877685595212919784447924875428848331771524426361483392903320495411973587861)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0621793463102927384924303843912913542297042029136293808338022462765755471002366206711862637)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.00701366932085103924241526535768453911099671087892444015581511551813219720807206445462785293)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.000691040514756294308758606917671220770856269030526647010461217455799229645004351524024364997)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.591529398871361458428147660822525365922497109038495896497692806150033516658042357799869656e-4)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.437237367535177689875119370170434437030440227275583289093139147244747901678407875809020739e-5)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.277164853397051135996651958345647824709602266382721185838782221179129726200661453504250697e-6)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.149506899012035980148891401548317536032574502641368034781671941165064546410613201579653674e-7)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.68023824066463262779882895193964639544061678698791279217407325790147925675797085217462974e-9)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.258460163734186329938721529982859244969655253624066115559707985878606277800329299821882688e-10)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.810792256024669306744649981276512583535251727474303382740940985102669076169168931092026491e-12)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.207274966207031327521921078048021807442500113231320959236850963529304158700096495799022922e-13)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.425399199286327802950259994834798737777721414442095221716122926637623478450472871269742436e-15)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.688866766744198529064607574117697940084548375790020728788313274612845280173338912495478431e-17)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.862599751805643281578607291655858333628582704771553874199104377131082877406179933909898885e-19)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.815756005678735657200275584442908437977926312650210429668619446123450972547018343768177988e-21)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.566583084099007858124915716926967268295318152203932871370429534546567151650626184750291695e-23)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.279544761599725082805446124351997692260093135930731230328454667675190245860598623539891708e-25)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.941169851584987983984201821679114408126982142904386301937192011680047611188837432096199601e-28)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.205866011331040736302780507155525142187875191518455173304638008169488993406425201915370746e-30)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.27526655245712584371295491216289353976964567057707464008951584303679019796521332324352501e-33)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.208358067979444305082929004102609366169534624348056112144990933897581971394396210379638792e-36)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.808728107661779323263133007119729988596844663194254976820030366188579170595441991680169012e-40)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.141276924383478964519776436955079978012672985961918248012931336621229652792338950573694356e-43)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.930318449287651389310440021745842417218125582685428432576258687100661462527604238849332053e-48)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.179870748819321661641184169834635133045197146966203370650788171790610563029431722308057539e-52)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.705865243912790337263229413370018392321238639017433365017168104310561824133229343750737083e-58)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3146787805734405996448268100558028857930560442377698646099945108125281507396722995748398e-64)),
|
||||
static_cast<T>(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<class T>
|
||||
static T lanczos_sum_near_1(const T& dz)
|
||||
{
|
||||
lanczos_initializer<lanczos61UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
using namespace boost;
|
||||
static const T d[60] = {
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 23.2463658527729692390378860713647146932236940604550445351214987229819352880524561852919518)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -523.358012551815715084547614110229469295755088686612838322817729744722233637819564673967396)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 5701.12892340421080714956066268650092612647620400476183901625272640935853188559347587495571)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -40033.5506451901904954336453419007623117537868026994808919201793803506999271787018654246699)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 203689.884259074923009439144410340256983393397995558814367995938668111650624499963153485034)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -800270.648969745331278757692597096167418585957703057412758177038340791380011708874081291202)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 2526668.23380061659863999395867315313385499515711742092815402701950519696944982260718031476)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -6587362.57559198722630391278043503867973853468105110382293763174847657538179665571836023631)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 14462211.3454541602975917764900442754186801975533106565506542322063393991552960595701762805)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -27132375.1879227404375395522940895789625516798992585980380939378508607160857820002128106898)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 43991923.8735251977856804364757478459275087361742168436524951824945035673768875988985478116)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -62192284.0030124679010201921841372967696262036115679150017649233887633598058364494608060812)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 77203473.0770033513405070667417251568915937590689150831268228886281254637715669678358204991)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -84630180.2217173903516348977915150565994784278120192219937728967986198118628659866582594874)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 82294807.2253549409847505891112074804416229757832871133388349982640444405470371147991706317)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -71245738.2484649177928765605893043553453557808557887270209768163561363857395639001251515788)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 55073334.3180266913441333534260714059077572215147571872597651029894142803987981342430068594)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -38097984.1648990787690036742690550656061009857688125101191167768314179751258568264424911474)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 23625729.5032184580395130592017474282828236643586203914515183078852982915252442161768527976)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -13149998.4348054726172055622442157883429575511528431835657668083088902165366619827169829685)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 6574597.77221556423683199818131482663205682902023554728024972161230111356285973623550338976)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -2953848.1483469149918109110050192571921018042012905892107136410603990336401921230407043408)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1192595.29584357246380113611351829515963605337523874715861849584306265512819543347806085356)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -432553.812019608638388918135375154289816441900572658692369491476137741687213006403648722272)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 140843.215385933866391177743292449477205328233960902455943995092958295858485718885800427129)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -41128.186992679630058614841985110676526199977321524879849001760603476646382839182691529968)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 10756.2849191854701631989789887757784944313743544315113894758328432005767448056040879337769)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -2515.15559672041299884426826962296210458052543246529646213159169885444118227871246315458787)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 524.750087004805200600237632074908875763734578390662349666321453103782638818305404274166951)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -97.4468596421732493988298219295878130651986131393383646674144877163795143930682205035917965)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 16.0613108128210806736384551896802799172445298357754547684100294231532127326987175444453058)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -2.34194813526540240672426202485306862230641838409943369059203455578340880900483887447559874)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.300982934748016059399829007219431333744032924923669397318820178988611410275964499475465815)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.033950095985367909789000959795708551814461844488183964432565731809399824963680858993718525)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.00334502394288921146242772614150438404658527112198421937945605441697314216921393987758378122)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.000286333429067523984607730553301991502191011265745476190940771685897687956262049750683013485)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.211647426149364947402896718485536530479491688838087899435991994237067890628274492042231115e-4)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.134163345121302758109675190598169832775248626443483098532368562186356128620805552609175683e-5)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.723697303042715085329782938306424498336642078597508935450663080894255773653328980495047891e-7)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.329273487343139063533251321553223583999676337945788660475231347828772272134656322947906888e-8)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.12510922551028971731767784013117088894558604838820475961392154031378891971216135267744134e-9)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.392468958215589939603666430583400537413757786057185505426804034745840192914621891690369903e-11)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.100332717101049934370760667782927946803279422001380028508200697081188326364078428184546051e-12)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.205917088291197705194762747639836655808855850989058813560983717575008725393428497910009756e-14)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.333450178247893143608439314203175490705783992567107481617660357577257627854979230819461489e-16)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.417546693906616047110563550428133589051498362676394888715581845170969319500638944065594319e-18)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.394871691642184410859178529844325390739857256666676534513661579365702353214518478078730801e-20)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.274258012587811199757875927548699264063511843669070634471054184977334027224611843434000922e-22)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.135315354265459854889496635967343027244391821142592599244505313738163473730636430399785048e-24)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.455579032003288910408487905303223613382276173706542364543918076752861628464036586507967767e-27)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.99650703862462739161520123768147312466695159780582506041370833824093136783202694548427718e-30)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1332444609228706921659395801935919548447859029572115502899861345555006827214220195650058e-32)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.100856999148765307000182397631280249632761913433008379786888200467467364474581430670889392e-35)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.39146979455613683472384690509165395074425354524713697428673406058157887065953366609738731e-39)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.683859606707931248105140296850112494069265272540298100341919970496564103098283709868586478e-43)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.450326344248604222735147147805963966503893913752040066400766411031387063854141246972061792e-47)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.870675378039492904184581895322153006461319724931909799151743284769901586333730037761678891e-52)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.341678395249272265744518787745356400350877656459401143889000625280131819505857966769964401e-57)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.152322191370871666358069530949353871960316638394428595988162174042653299702098929238880862e-63)),
|
||||
static_cast<T>(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<class T>
|
||||
static T lanczos_sum_near_2(const T& dz)
|
||||
{
|
||||
lanczos_initializer<lanczos61UDT, T>::force_instantiate(); // Ensure our constants get initialized before main()
|
||||
using namespace boost;
|
||||
static const T d[60] = {
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 557.56438192770795764344217888434355281097193198928944200046501607026919782564033547346298)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -12552.748616427645475141433405567201788681683808077269330800392600825597799119572762385222)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 136741.650054039199076788077149441364242294724343897779563222338447737802381279007988884806)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -960205.223613240309942047656967301131022760634321049075674684679438471862998829007639437133)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 4885504.47588736223774859617054275229642041717942140469884121916073195308537421162982679289)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -19194501.738192166918904824982935279260356575935661514109550613809352009246483412530545583)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 60602169.8633537742937457094837494059849674261357199218329545854990149896822944801504450843)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -157997975.522506767297528502540724511908584668874487506510120462561270100749019845014382885)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 346876323.86092543685419723290495817330608574729543216092477261152247521712190505658568876)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -650770365.471136883718747607976242475416651908858429752332176373467422603953536408709972919)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1055146856.05909309330903130910708372830487315684258450293308627289334336871273080305128138)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1491682726.25614447429071368736790697283307005456720192465860871846879804207692411263924608)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1851726287.94866167094858600116562210167031458934987154557042242638980748286188183300900268)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -2029855953.68334371445800569238095379629407314338521720558391277508374519526853827142679839)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1973842002.53354868177824629525448788555435194808657489238517523691040148611221295436287925)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -1708829941.98209573247426625323314413060108441455314880934710595647408841619484540679859098)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 1320934627.12433688699625456833930317624783222321555050330381730035733198249283009357314954)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -913780636.858542526294419197161614811332299249415125108737474024007693329922089123296358727)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 566663423.929632170286007468016419798879660054391183200464733820209439185545886930103546787)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -315402880.436816230388857961460509181823167373029384218959199936902955049832392362044305869)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 157691811.550465734461741500275930418786875005567018699867961482249002625886064187146134966)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -70848085.5705405970640618473551954585013808128304384354476488268600720054598122945113512731)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 28604413.4050137708444142264980840059788755325900041515286382001704951527733220637586013815)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -10374808.7067303054787164054055989420809074792801592763124972441820101840292558840131568633)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 3378126.32016207486657791623723515804931231041318964254116390764473281291389374196880720069)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -986460.090390653140964189383080344920103075349535669020623874668558777188889544398718979744)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 257989.631187387317948158483575125380011593209850756066176921901006833159795100137743395985)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -60326.0391159227288325790327830741260824763549807922845004854215660451399733578621565837087)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 12586.1375399649496159880821645216260841794563919652590583420570326276086323953958907053394)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -2337.26417330316922535871922886167444795452055677161063205953141105726549966801856628447293)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 385.230745012608736644117458716226876976056390433401632749144285378123105481506733917763829)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -56.1716559403731491675970177460841997333796694857076749852739159067307309470690838101179615)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 7.21907953468550196348585224042498727840087634483369357697580053424523903859773769748599575)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.814293485887386870805786409956942772883474224091975496298369877683530509729332902182019049)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0802304419995150047616460464220884371214157889148846405799324851793571580868840034085001373)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.00686771095380619535195996193943858680694970000948742557733102777115482017857981277171196115)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.000507636621977556438232617777542864427109623356049335590894564220687567763620803789858345916)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.32179095465362720747836116655088181481893063531138957363431280817392443948706754917605911e-4)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.173578890579848508947329833426585354230744194615295570820295052665075101971588563893718407e-5)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.789762880006288893888161070734302768702358633525134582027140158619195373770299678322596835e-7)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.300074637200885066788470310738617992259402710843493097610337134266720909870967550606601658e-8)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.941337297619721713151110244242536308266701344868601679868536153775533330272973088246835359e-10)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.24064815013182536657310186836079333949814111498828401548170442715552017773994482539471456e-11)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.493892399304811910466345686492277504628763169549384435563232052965821874553923373100791477e-13)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.799780678476644196901221989475355609743387528732994566453160178199295104357319723742820593e-15)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.100148627870893347527249092785257443532967736956154251497569191947184705954310833302770086e-16)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.947100256812658897084619699699028861352615460106539259289295071616221848196411749449858071e-19)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.657808193528898116367845405906343884364280888644748907819280236995018351085371701094007759e-21)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.324554050057463845012469010247790763753999056976705084126950591088538742509983426730851614e-23)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.10927068902162908990029309141242256163212535730975970310918370355165185052827948996110107e-25)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.239012340507870646690121104637467232366271566488184795459093215303237974655782634371712486e-28)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.31958700972990573259359660326375143524864710953063781494908314884519046349402409667329667e-31)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.241905641292988284384362036555782113275737930713192053073501265726048089991747342247551645e-34)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.93894080230619233745797029179332447129464915420290457418429337322820997038069119047864035e-38)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.164023814025085488413251990798690797467351995518990067783355251949198292596815470576539877e-41)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.108010831192689925518484618970761942019888832176355541674171850211917230280206410356465451e-45)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.208831600642796805563854019033577205240227465154130766898180386564934443551840379116390645e-50)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.819516067465171848863933747691434138146789031214932473898084756489529673230665363014007306e-56)),
|
||||
static_cast<T>(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.365344970579318347488211604761724311582675708113250505307342682118101409913523622073678179e-62)),
|
||||
static_cast<T>(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
|
||||
|
||||
|
||||
974
third-party/boost-math/include/boost/math/bindings/mpfr.hpp
vendored
Normal file
974
third-party/boost-math/include/boost/math/bindings/mpfr.hpp
vendored
Normal file
@ -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 <type_traits>
|
||||
|
||||
#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 <gmpfrxx.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
#include <boost/math/tools/real_cast.hpp>
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/math_fwd.hpp>
|
||||
#include <boost/math/bindings/detail/big_digamma.hpp>
|
||||
#include <boost/math/bindings/detail/big_lanczos.hpp>
|
||||
#include <boost/math/tools/big_constant.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
|
||||
inline mpfr_class fabs(const mpfr_class& v)
|
||||
{
|
||||
return abs(v);
|
||||
}
|
||||
template <class T, class U>
|
||||
inline mpfr_class fabs(const __gmp_expr<T,U>& v)
|
||||
{
|
||||
return abs(static_cast<mpfr_class>(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 <class T, class U, class V, class W>
|
||||
inline mpfr_class pow(const __gmp_expr<T,U>& b, const __gmp_expr<V,W>& e)
|
||||
{
|
||||
return pow(static_cast<mpfr_class>(b), static_cast<mpfr_class>(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 <class T, class U>
|
||||
inline mpfr_class ldexp(const __gmp_expr<T,U>& v, int e)
|
||||
{
|
||||
return ldexp(static_cast<mpfr_class>(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 <class T, class U>
|
||||
inline mpfr_class frexp(const __gmp_expr<T,U>& v, int* expon)
|
||||
{
|
||||
return frexp(static_cast<mpfr_class>(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 <class T, class U, class V, class W>
|
||||
inline mpfr_class fmod(const __gmp_expr<T,U>& v1, const __gmp_expr<V,W>& v2)
|
||||
{
|
||||
return fmod(static_cast<mpfr_class>(v1), static_cast<mpfr_class>(v2));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
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<mpfr_class>(*ipart);
|
||||
}
|
||||
template <class T, class U, class Policy>
|
||||
inline mpfr_class modf(const __gmp_expr<T,U>& v, long long* ipart, const Policy& pol)
|
||||
{
|
||||
return modf(static_cast<mpfr_class>(v), ipart, pol);
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline int iround(mpfr_class const& x, const Policy&)
|
||||
{
|
||||
return boost::math::tools::real_cast<int>(boost::math::round(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
|
||||
}
|
||||
template <class T, class U, class Policy>
|
||||
inline int iround(__gmp_expr<T,U> const& x, const Policy& pol)
|
||||
{
|
||||
return iround(static_cast<mpfr_class>(x), pol);
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long lround(mpfr_class const& x, const Policy&)
|
||||
{
|
||||
return boost::math::tools::real_cast<long>(boost::math::round(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
|
||||
}
|
||||
template <class T, class U, class Policy>
|
||||
inline long lround(__gmp_expr<T,U> const& x, const Policy& pol)
|
||||
{
|
||||
return lround(static_cast<mpfr_class>(x), pol);
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long long llround(mpfr_class const& x, const Policy&)
|
||||
{
|
||||
return boost::math::tools::real_cast<long long>(boost::math::round(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
|
||||
}
|
||||
template <class T, class U, class Policy>
|
||||
inline long long llround(__gmp_expr<T,U> const& x, const Policy& pol)
|
||||
{
|
||||
return llround(static_cast<mpfr_class>(x), pol);
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline int itrunc(mpfr_class const& x, const Policy&)
|
||||
{
|
||||
return boost::math::tools::real_cast<int>(boost::math::trunc(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
|
||||
}
|
||||
template <class T, class U, class Policy>
|
||||
inline int itrunc(__gmp_expr<T,U> const& x, const Policy& pol)
|
||||
{
|
||||
return itrunc(static_cast<mpfr_class>(x), pol);
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long ltrunc(mpfr_class const& x, const Policy&)
|
||||
{
|
||||
return boost::math::tools::real_cast<long>(boost::math::trunc(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
|
||||
}
|
||||
template <class T, class U, class Policy>
|
||||
inline long ltrunc(__gmp_expr<T,U> const& x, const Policy& pol)
|
||||
{
|
||||
return ltrunc(static_cast<mpfr_class>(x), pol);
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long long lltrunc(mpfr_class const& x, const Policy&)
|
||||
{
|
||||
return boost::math::tools::real_cast<long long>(boost::math::trunc(x, typename boost::math::policies::normalise<Policy, boost::math::policies::rounding_error< boost::math::policies::throw_on_error> >::type()));
|
||||
}
|
||||
template <class T, class U, class Policy>
|
||||
inline long long lltrunc(__gmp_expr<T,U> const& x, const Policy& pol)
|
||||
{
|
||||
return lltrunc(static_cast<mpfr_class>(x), pol);
|
||||
}
|
||||
|
||||
namespace boost{
|
||||
|
||||
#ifdef BOOST_MATH_USE_FLOAT128
|
||||
template<> struct std::is_convertible<BOOST_MATH_FLOAT128_TYPE, mpfr_class> : public std::integral_constant<bool, false>{};
|
||||
#endif
|
||||
template<> struct std::is_convertible<long long, mpfr_class> : public std::integral_constant<bool, false>{};
|
||||
|
||||
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<class Policy>
|
||||
struct lanczos<mpfr_class, Policy>
|
||||
{
|
||||
typedef mpfr_lanczos type;
|
||||
};
|
||||
|
||||
} // namespace lanczos
|
||||
|
||||
namespace constants{
|
||||
|
||||
template <class Real, class Policy>
|
||||
struct construction_traits;
|
||||
|
||||
template <class Policy>
|
||||
struct construction_traits<mpfr_class, Policy>
|
||||
{
|
||||
typedef std::integral_constant<int, 0> type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace tools
|
||||
{
|
||||
|
||||
template <class T, class U>
|
||||
struct promote_arg<__gmp_expr<T,U> >
|
||||
{ // If T is integral type, then promote to double.
|
||||
typedef mpfr_class type;
|
||||
};
|
||||
|
||||
template<>
|
||||
inline int digits<mpfr_class>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) noexcept
|
||||
{
|
||||
return mpfr_class::get_dprec();
|
||||
}
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<class Integer>
|
||||
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<double>(t);
|
||||
last_result = result;
|
||||
result += static_cast<I>(term);
|
||||
t -= term;
|
||||
}while(result != last_result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
inline mpfr_class real_cast<mpfr_class, long long>(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<double>(t & 0xffffL), expon);
|
||||
expon += 32;
|
||||
t >>= 32;
|
||||
}
|
||||
return result * sign;
|
||||
}
|
||||
template <>
|
||||
inline unsigned real_cast<unsigned, mpfr_class>(mpfr_class t)
|
||||
{
|
||||
return t.get_ui();
|
||||
}
|
||||
template <>
|
||||
inline int real_cast<int, mpfr_class>(mpfr_class t)
|
||||
{
|
||||
return t.get_si();
|
||||
}
|
||||
template <>
|
||||
inline double real_cast<double, mpfr_class>(mpfr_class t)
|
||||
{
|
||||
return t.get_d();
|
||||
}
|
||||
template <>
|
||||
inline float real_cast<float, mpfr_class>(mpfr_class t)
|
||||
{
|
||||
return static_cast<float>(t.get_d());
|
||||
}
|
||||
template <>
|
||||
inline long real_cast<long, mpfr_class>(mpfr_class t)
|
||||
{
|
||||
long result;
|
||||
detail::convert_to_long_result(t, result);
|
||||
return result;
|
||||
}
|
||||
template <>
|
||||
inline long long real_cast<long long, mpfr_class>(mpfr_class t)
|
||||
{
|
||||
long long result;
|
||||
detail::convert_to_long_result(t, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline mpfr_class max_value<mpfr_class>(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<mpfr_class>(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<mpfr_class>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class))
|
||||
{
|
||||
static bool has_init = false;
|
||||
static mpfr_class val = max_value<mpfr_class>();
|
||||
if(!has_init)
|
||||
{
|
||||
val = log(val);
|
||||
has_init = true;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline mpfr_class log_min_value<mpfr_class>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class))
|
||||
{
|
||||
static bool has_init = false;
|
||||
static mpfr_class val = max_value<mpfr_class>();
|
||||
if(!has_init)
|
||||
{
|
||||
val = log(val);
|
||||
has_init = true;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline mpfr_class epsilon<mpfr_class>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class))
|
||||
{
|
||||
return ldexp(mpfr_class(1), 1-boost::math::policies::digits<mpfr_class, boost::math::policies::policy<> >());
|
||||
}
|
||||
|
||||
} // namespace tools
|
||||
|
||||
namespace policies{
|
||||
|
||||
template <class T, class U, class Policy>
|
||||
struct evaluation<__gmp_expr<T, U>, Policy>
|
||||
{
|
||||
typedef mpfr_class type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline mpfr_class skewness(const extreme_value_distribution<mpfr_class, Policy>& /*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<mpfr_class>("1.1395470994046486574927930193898461120875997958366");
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline mpfr_class skewness(const rayleigh_distribution<mpfr_class, Policy>& /*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<mpfr_class>("0.63111065781893713819189935154422777984404221106391");
|
||||
// Computed using NTL at 150 bit, about 50 decimal digits.
|
||||
// return 2 * root_pi<RealType>() * pi_minus_three<RealType>() / pow23_four_minus_pi<RealType>();
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline mpfr_class kurtosis(const rayleigh_distribution<mpfr_class, Policy>& /*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<mpfr_class>("3.2450893006876380628486604106197544154170667057995");
|
||||
// Computed using NTL at 150 bit, about 50 decimal digits.
|
||||
// return 3 - (6 * pi<RealType>() * pi<RealType>() - 24 * pi<RealType>() + 16) /
|
||||
// (four_minus_pi<RealType>() * four_minus_pi<RealType>());
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline mpfr_class kurtosis_excess(const rayleigh_distribution<mpfr_class, Policy>& /*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<mpfr_class>("0.2450893006876380628486604106197544154170667057995");
|
||||
// return -(6 * pi<RealType>() * pi<RealType>() - 24 * pi<RealType>() + 16) /
|
||||
// (four_minus_pi<RealType>() * four_minus_pi<RealType>());
|
||||
} // kurtosis
|
||||
|
||||
namespace detail{
|
||||
|
||||
//
|
||||
// Version of Digamma accurate to ~100 decimal digits.
|
||||
//
|
||||
template <class Policy>
|
||||
mpfr_class digamma_imp(mpfr_class x, const std::integral_constant<int, 0>* , 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<mpfr_class>("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol);
|
||||
}
|
||||
result = constants::pi<mpfr_class>() / tan(constants::pi<mpfr_class>() * remainder);
|
||||
}
|
||||
result += big_digamma(x);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// Specialisations of this function provides the initial
|
||||
// starting guess for Halley iteration:
|
||||
//
|
||||
template <class Policy>
|
||||
inline mpfr_class erf_inv_imp(const mpfr_class& p, const mpfr_class& q, const Policy&, const std::integral_constant<int, 64>*)
|
||||
{
|
||||
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<mpfr_class>("-2.2335582639474375249e+15"),
|
||||
static_cast<mpfr_class>("-5.5050369673018427753e+14"),
|
||||
static_cast<mpfr_class>("-3.2940087627407749166e+13"),
|
||||
static_cast<mpfr_class>("-8.4925101247114157499e+11"),
|
||||
static_cast<mpfr_class>("-1.1912746104985237192e+10"),
|
||||
static_cast<mpfr_class>("-1.0313066708737980747e+08"),
|
||||
static_cast<mpfr_class>("-5.9545626019847898221e+05"),
|
||||
static_cast<mpfr_class>("-2.4125195876041896775e+03"),
|
||||
static_cast<mpfr_class>("-7.0935347449210549190e+00"),
|
||||
static_cast<mpfr_class>("-1.5453977791786851041e-02"),
|
||||
static_cast<mpfr_class>("-2.5172644670688975051e-05"),
|
||||
static_cast<mpfr_class>("-3.0517226450451067446e-08"),
|
||||
static_cast<mpfr_class>("-2.6843448573468483278e-11"),
|
||||
static_cast<mpfr_class>("-1.5982226675653184646e-14"),
|
||||
static_cast<mpfr_class>("-5.2487866627945699800e-18"),
|
||||
};
|
||||
static const mpfr_class Q1[] = {
|
||||
static_cast<mpfr_class>("-2.2335582639474375245e+15"),
|
||||
static_cast<mpfr_class>("7.8858692566751002988e+12"),
|
||||
static_cast<mpfr_class>("-1.2207067397808979846e+10"),
|
||||
static_cast<mpfr_class>("1.0377081058062166144e+07"),
|
||||
static_cast<mpfr_class>("-4.8527560179962773045e+03"),
|
||||
static_cast<mpfr_class>("1.0"),
|
||||
};
|
||||
static const mpfr_class P2[] = {
|
||||
static_cast<mpfr_class>("-2.2210262233306573296e-04"),
|
||||
static_cast<mpfr_class>("1.3067392038106924055e-02"),
|
||||
static_cast<mpfr_class>("-4.4700805721174453923e-01"),
|
||||
static_cast<mpfr_class>("5.5674518371240761397e+00"),
|
||||
static_cast<mpfr_class>("-2.3517945679239481621e+01"),
|
||||
static_cast<mpfr_class>("3.1611322818701131207e+01"),
|
||||
static_cast<mpfr_class>("-9.6090021968656180000e+00"),
|
||||
};
|
||||
static const mpfr_class Q2[] = {
|
||||
static_cast<mpfr_class>("-5.5194330231005480228e-04"),
|
||||
static_cast<mpfr_class>("3.2547697594819615062e-02"),
|
||||
static_cast<mpfr_class>("-1.1151759188741312645e+00"),
|
||||
static_cast<mpfr_class>("1.3982595353892851542e+01"),
|
||||
static_cast<mpfr_class>("-6.0228002066743340583e+01"),
|
||||
static_cast<mpfr_class>("8.5539563258012929600e+01"),
|
||||
static_cast<mpfr_class>("-3.1446690275135491500e+01"),
|
||||
static_cast<mpfr_class>("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<mpfr_class>(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<mpfr_class>("-1.4577180278143463643e+15"),
|
||||
static_cast<mpfr_class>("-1.7732037840791591320e+14"),
|
||||
static_cast<mpfr_class>("-6.9876779648010090070e+12"),
|
||||
static_cast<mpfr_class>("-1.3357437682275493024e+11"),
|
||||
static_cast<mpfr_class>("-1.4828267606612366099e+09"),
|
||||
static_cast<mpfr_class>("-1.0588550724769347106e+07"),
|
||||
static_cast<mpfr_class>("-5.1894091982308017540e+04"),
|
||||
static_cast<mpfr_class>("-1.8225946631657315931e+02"),
|
||||
static_cast<mpfr_class>("-4.7207090827310162436e-01"),
|
||||
static_cast<mpfr_class>("-9.1746443287817501309e-04"),
|
||||
static_cast<mpfr_class>("-1.3466829827635152875e-06"),
|
||||
static_cast<mpfr_class>("-1.4831904935994647675e-09"),
|
||||
static_cast<mpfr_class>("-1.1928788903603238754e-12"),
|
||||
static_cast<mpfr_class>("-6.5245515583151902910e-16"),
|
||||
static_cast<mpfr_class>("-1.9705291802535139930e-19"),
|
||||
};
|
||||
static const mpfr_class Q1[] = {
|
||||
static_cast<mpfr_class>("-2.9154360556286927285e+15"),
|
||||
static_cast<mpfr_class>("9.7887501377547640438e+12"),
|
||||
static_cast<mpfr_class>("-1.4386907088588283434e+10"),
|
||||
static_cast<mpfr_class>("1.1594225856856884006e+07"),
|
||||
static_cast<mpfr_class>("-5.1326864679904189920e+03"),
|
||||
static_cast<mpfr_class>("1.0"),
|
||||
};
|
||||
static const mpfr_class P2[] = {
|
||||
static_cast<mpfr_class>("1.4582087408985668208e-05"),
|
||||
static_cast<mpfr_class>("-8.9359825138577646443e-04"),
|
||||
static_cast<mpfr_class>("2.9204895411257790122e-02"),
|
||||
static_cast<mpfr_class>("-3.4198728018058047439e-01"),
|
||||
static_cast<mpfr_class>("1.3960118277609544334e+00"),
|
||||
static_cast<mpfr_class>("-1.9746376087200685843e+00"),
|
||||
static_cast<mpfr_class>("8.5591872901933459000e-01"),
|
||||
static_cast<mpfr_class>("-6.0437159056137599999e-02"),
|
||||
};
|
||||
static const mpfr_class Q2[] = {
|
||||
static_cast<mpfr_class>("3.7510433111922824643e-05"),
|
||||
static_cast<mpfr_class>("-2.2835624489492512649e-03"),
|
||||
static_cast<mpfr_class>("7.4212010813186530069e-02"),
|
||||
static_cast<mpfr_class>("-8.5017476463217924408e-01"),
|
||||
static_cast<mpfr_class>("3.2593714889036996297e+00"),
|
||||
static_cast<mpfr_class>("-3.8806586721556593450e+00"),
|
||||
static_cast<mpfr_class>("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<mpfr_class>(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<long double, mpfr_class> : public std::false_type{};
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_MATH_MPLFR_BINDINGS_HPP
|
||||
|
||||
921
third-party/boost-math/include/boost/math/bindings/mpreal.hpp
vendored
Normal file
921
third-party/boost-math/include/boost/math/bindings/mpreal.hpp
vendored
Normal file
@ -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 <type_traits>
|
||||
|
||||
#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 <mpreal.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
#include <boost/math/tools/real_cast.hpp>
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/math_fwd.hpp>
|
||||
#include <boost/math/bindings/detail/big_digamma.hpp>
|
||||
#include <boost/math/bindings/detail/big_lanczos.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#ifndef BOOST_MATH_STANDALONE
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#endif
|
||||
|
||||
namespace mpfr{
|
||||
|
||||
template <class T>
|
||||
inline mpreal operator + (const mpreal& r, const T& t){ return r + mpreal(t); }
|
||||
template <class T>
|
||||
inline mpreal operator - (const mpreal& r, const T& t){ return r - mpreal(t); }
|
||||
template <class T>
|
||||
inline mpreal operator * (const mpreal& r, const T& t){ return r * mpreal(t); }
|
||||
template <class T>
|
||||
inline mpreal operator / (const mpreal& r, const T& t){ return r / mpreal(t); }
|
||||
|
||||
template <class T>
|
||||
inline mpreal operator + (const T& t, const mpreal& r){ return mpreal(t) + r; }
|
||||
template <class T>
|
||||
inline mpreal operator - (const T& t, const mpreal& r){ return mpreal(t) - r; }
|
||||
template <class T>
|
||||
inline mpreal operator * (const T& t, const mpreal& r){ return mpreal(t) * r; }
|
||||
template <class T>
|
||||
inline mpreal operator / (const T& t, const mpreal& r){ return mpreal(t) / r; }
|
||||
|
||||
template <class T>
|
||||
inline bool operator == (const mpreal& r, const T& t){ return r == mpreal(t); }
|
||||
template <class T>
|
||||
inline bool operator != (const mpreal& r, const T& t){ return r != mpreal(t); }
|
||||
template <class T>
|
||||
inline bool operator <= (const mpreal& r, const T& t){ return r <= mpreal(t); }
|
||||
template <class T>
|
||||
inline bool operator >= (const mpreal& r, const T& t){ return r >= mpreal(t); }
|
||||
template <class T>
|
||||
inline bool operator < (const mpreal& r, const T& t){ return r < mpreal(t); }
|
||||
template <class T>
|
||||
inline bool operator > (const mpreal& r, const T& t){ return r > mpreal(t); }
|
||||
|
||||
template <class T>
|
||||
inline bool operator == (const T& t, const mpreal& r){ return mpreal(t) == r; }
|
||||
template <class T>
|
||||
inline bool operator != (const T& t, const mpreal& r){ return mpreal(t) != r; }
|
||||
template <class T>
|
||||
inline bool operator <= (const T& t, const mpreal& r){ return mpreal(t) <= r; }
|
||||
template <class T>
|
||||
inline bool operator >= (const T& t, const mpreal& r){ return mpreal(t) >= r; }
|
||||
template <class T>
|
||||
inline bool operator < (const T& t, const mpreal& r){ return mpreal(t) < r; }
|
||||
template <class T>
|
||||
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<mp_exp_t>(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 <class Policy>
|
||||
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<mpfr::mpreal>(*ipart);
|
||||
}
|
||||
template <class Policy>
|
||||
inline int iround(mpfr::mpreal const& x, const Policy& pol)
|
||||
{
|
||||
return boost::math::tools::real_cast<int>(boost::math::round(x, pol));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long lround(mpfr::mpreal const& x, const Policy& pol)
|
||||
{
|
||||
return boost::math::tools::real_cast<long>(boost::math::round(x, pol));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long long llround(mpfr::mpreal const& x, const Policy& pol)
|
||||
{
|
||||
return boost::math::tools::real_cast<long long>(boost::math::round(x, pol));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline int itrunc(mpfr::mpreal const& x, const Policy& pol)
|
||||
{
|
||||
return boost::math::tools::real_cast<int>(boost::math::trunc(x, pol));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long ltrunc(mpfr::mpreal const& x, const Policy& pol)
|
||||
{
|
||||
return boost::math::tools::real_cast<long>(boost::math::trunc(x, pol));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long long lltrunc(mpfr::mpreal const& x, const Policy& pol)
|
||||
{
|
||||
return boost::math::tools::real_cast<long long>(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<class Policy>
|
||||
struct lanczos<mpfr::mpreal, Policy>
|
||||
{
|
||||
typedef mpreal_lanczos type;
|
||||
};
|
||||
|
||||
} // namespace lanczos
|
||||
|
||||
namespace tools
|
||||
{
|
||||
|
||||
template<>
|
||||
inline int digits<mpfr::mpreal>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal))
|
||||
{
|
||||
return mpfr::mpreal::get_default_prec();
|
||||
}
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<class Integer
|
||||
void convert_to_long_result(mpfr::mpreal const& r, Integer& result)
|
||||
{
|
||||
result = 0;
|
||||
I last_result(0);
|
||||
mpfr::mpreal t(r);
|
||||
double term;
|
||||
do
|
||||
{
|
||||
term = real_cast<double>(t);
|
||||
last_result = result;
|
||||
result += static_cast<I>(term);
|
||||
t -= term;
|
||||
}while(result != last_result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
inline mpfr::mpreal real_cast<mpfr::mpreal, long long>(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<double>(t & 0xffffL), expon);
|
||||
expon += 32;
|
||||
t >>= 32;
|
||||
}
|
||||
return result * sign;
|
||||
}
|
||||
/*
|
||||
template <>
|
||||
inline unsigned real_cast<unsigned, mpfr::mpreal>(mpfr::mpreal t)
|
||||
{
|
||||
return t.get_ui();
|
||||
}
|
||||
template <>
|
||||
inline int real_cast<int, mpfr::mpreal>(mpfr::mpreal t)
|
||||
{
|
||||
return t.get_si();
|
||||
}
|
||||
template <>
|
||||
inline double real_cast<double, mpfr::mpreal>(mpfr::mpreal t)
|
||||
{
|
||||
return t.get_d();
|
||||
}
|
||||
template <>
|
||||
inline float real_cast<float, mpfr::mpreal>(mpfr::mpreal t)
|
||||
{
|
||||
return static_cast<float>(t.get_d());
|
||||
}
|
||||
template <>
|
||||
inline long real_cast<long, mpfr::mpreal>(mpfr::mpreal t)
|
||||
{
|
||||
long result;
|
||||
detail::convert_to_long_result(t, result);
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
template <>
|
||||
inline long long real_cast<long long, mpfr::mpreal>(mpfr::mpreal t)
|
||||
{
|
||||
long long result;
|
||||
detail::convert_to_long_result(t, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline mpfr::mpreal max_value<mpfr::mpreal>(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<mpfr::mpreal>(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<mpfr::mpreal>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal))
|
||||
{
|
||||
static bool has_init = false;
|
||||
static mpfr::mpreal val = max_value<mpfr::mpreal>();
|
||||
if(!has_init)
|
||||
{
|
||||
val = log(val);
|
||||
has_init = true;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline mpfr::mpreal log_min_value<mpfr::mpreal>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal))
|
||||
{
|
||||
static bool has_init = false;
|
||||
static mpfr::mpreal val = max_value<mpfr::mpreal>();
|
||||
if(!has_init)
|
||||
{
|
||||
val = log(val);
|
||||
has_init = true;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline mpfr::mpreal epsilon<mpfr::mpreal>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal))
|
||||
{
|
||||
return ldexp(mpfr::mpreal(1), 1-boost::math::policies::digits<mpfr::mpreal, boost::math::policies::policy<> >());
|
||||
}
|
||||
|
||||
} // namespace tools
|
||||
|
||||
template <class Policy>
|
||||
inline mpfr::mpreal skewness(const extreme_value_distribution<mpfr::mpreal, Policy>& /*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<mpfr::mpreal>("1.1395470994046486574927930193898461120875997958366");
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline mpfr::mpreal skewness(const rayleigh_distribution<mpfr::mpreal, Policy>& /*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<mpfr::mpreal>("0.63111065781893713819189935154422777984404221106391");
|
||||
// Computed using NTL at 150 bit, about 50 decimal digits.
|
||||
// return 2 * root_pi<RealType>() * pi_minus_three<RealType>() / pow23_four_minus_pi<RealType>();
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline mpfr::mpreal kurtosis(const rayleigh_distribution<mpfr::mpreal, Policy>& /*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<mpfr::mpreal>("3.2450893006876380628486604106197544154170667057995");
|
||||
// Computed using NTL at 150 bit, about 50 decimal digits.
|
||||
// return 3 - (6 * pi<RealType>() * pi<RealType>() - 24 * pi<RealType>() + 16) /
|
||||
// (four_minus_pi<RealType>() * four_minus_pi<RealType>());
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline mpfr::mpreal kurtosis_excess(const rayleigh_distribution<mpfr::mpreal, Policy>& /*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<mpfr::mpreal>("0.2450893006876380628486604106197544154170667057995");
|
||||
// return -(6 * pi<RealType>() * pi<RealType>() - 24 * pi<RealType>() + 16) /
|
||||
// (four_minus_pi<RealType>() * four_minus_pi<RealType>());
|
||||
} // kurtosis
|
||||
|
||||
namespace detail{
|
||||
|
||||
//
|
||||
// Version of Digamma accurate to ~100 decimal digits.
|
||||
//
|
||||
template <class Policy>
|
||||
mpfr::mpreal digamma_imp(mpfr::mpreal x, const std::integral_constant<int, 0>* , 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<mpfr::mpreal>("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol);
|
||||
}
|
||||
result = constants::pi<mpfr::mpreal>() / tan(constants::pi<mpfr::mpreal>() * remainder);
|
||||
}
|
||||
result += big_digamma(x);
|
||||
return result;
|
||||
}
|
||||
//
|
||||
// Specialisations of this function provides the initial
|
||||
// starting guess for Halley iteration:
|
||||
//
|
||||
template <class Policy>
|
||||
mpfr::mpreal erf_inv_imp(const mpfr::mpreal& p, const mpfr::mpreal& q, const Policy&, const std::integral_constant<int, 64>*)
|
||||
{
|
||||
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<mpfr::mpreal>("-2.2335582639474375249e+15"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-5.5050369673018427753e+14"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-3.2940087627407749166e+13"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-8.4925101247114157499e+11"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-1.1912746104985237192e+10"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-1.0313066708737980747e+08"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-5.9545626019847898221e+05"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-2.4125195876041896775e+03"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-7.0935347449210549190e+00"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-1.5453977791786851041e-02"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-2.5172644670688975051e-05"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-3.0517226450451067446e-08"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-2.6843448573468483278e-11"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-1.5982226675653184646e-14"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-5.2487866627945699800e-18"),
|
||||
};
|
||||
static const mpfr::mpreal Q1[] = {
|
||||
boost::lexical_cast<mpfr::mpreal>("-2.2335582639474375245e+15"),
|
||||
boost::lexical_cast<mpfr::mpreal>("7.8858692566751002988e+12"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-1.2207067397808979846e+10"),
|
||||
boost::lexical_cast<mpfr::mpreal>("1.0377081058062166144e+07"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-4.8527560179962773045e+03"),
|
||||
boost::lexical_cast<mpfr::mpreal>("1.0"),
|
||||
};
|
||||
static const mpfr::mpreal P2[] = {
|
||||
boost::lexical_cast<mpfr::mpreal>("-2.2210262233306573296e-04"),
|
||||
boost::lexical_cast<mpfr::mpreal>("1.3067392038106924055e-02"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-4.4700805721174453923e-01"),
|
||||
boost::lexical_cast<mpfr::mpreal>("5.5674518371240761397e+00"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-2.3517945679239481621e+01"),
|
||||
boost::lexical_cast<mpfr::mpreal>("3.1611322818701131207e+01"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-9.6090021968656180000e+00"),
|
||||
};
|
||||
static const mpfr::mpreal Q2[] = {
|
||||
boost::lexical_cast<mpfr::mpreal>("-5.5194330231005480228e-04"),
|
||||
boost::lexical_cast<mpfr::mpreal>("3.2547697594819615062e-02"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-1.1151759188741312645e+00"),
|
||||
boost::lexical_cast<mpfr::mpreal>("1.3982595353892851542e+01"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-6.0228002066743340583e+01"),
|
||||
boost::lexical_cast<mpfr::mpreal>("8.5539563258012929600e+01"),
|
||||
boost::lexical_cast<mpfr::mpreal>("-3.1446690275135491500e+01"),
|
||||
boost::lexical_cast<mpfr::mpreal>("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<mpfr::mpreal>(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<mpfr::mpreal>("-1.4577180278143463643e+15"),
|
||||
static_cast<mpfr::mpreal>("-1.7732037840791591320e+14"),
|
||||
static_cast<mpfr::mpreal>("-6.9876779648010090070e+12"),
|
||||
static_cast<mpfr::mpreal>("-1.3357437682275493024e+11"),
|
||||
static_cast<mpfr::mpreal>("-1.4828267606612366099e+09"),
|
||||
static_cast<mpfr::mpreal>("-1.0588550724769347106e+07"),
|
||||
static_cast<mpfr::mpreal>("-5.1894091982308017540e+04"),
|
||||
static_cast<mpfr::mpreal>("-1.8225946631657315931e+02"),
|
||||
static_cast<mpfr::mpreal>("-4.7207090827310162436e-01"),
|
||||
static_cast<mpfr::mpreal>("-9.1746443287817501309e-04"),
|
||||
static_cast<mpfr::mpreal>("-1.3466829827635152875e-06"),
|
||||
static_cast<mpfr::mpreal>("-1.4831904935994647675e-09"),
|
||||
static_cast<mpfr::mpreal>("-1.1928788903603238754e-12"),
|
||||
static_cast<mpfr::mpreal>("-6.5245515583151902910e-16"),
|
||||
static_cast<mpfr::mpreal>("-1.9705291802535139930e-19"),
|
||||
};
|
||||
static const mpfr::mpreal Q1[] = {
|
||||
static_cast<mpfr::mpreal>("-2.9154360556286927285e+15"),
|
||||
static_cast<mpfr::mpreal>("9.7887501377547640438e+12"),
|
||||
static_cast<mpfr::mpreal>("-1.4386907088588283434e+10"),
|
||||
static_cast<mpfr::mpreal>("1.1594225856856884006e+07"),
|
||||
static_cast<mpfr::mpreal>("-5.1326864679904189920e+03"),
|
||||
static_cast<mpfr::mpreal>("1.0"),
|
||||
};
|
||||
static const mpfr::mpreal P2[] = {
|
||||
static_cast<mpfr::mpreal>("1.4582087408985668208e-05"),
|
||||
static_cast<mpfr::mpreal>("-8.9359825138577646443e-04"),
|
||||
static_cast<mpfr::mpreal>("2.9204895411257790122e-02"),
|
||||
static_cast<mpfr::mpreal>("-3.4198728018058047439e-01"),
|
||||
static_cast<mpfr::mpreal>("1.3960118277609544334e+00"),
|
||||
static_cast<mpfr::mpreal>("-1.9746376087200685843e+00"),
|
||||
static_cast<mpfr::mpreal>("8.5591872901933459000e-01"),
|
||||
static_cast<mpfr::mpreal>("-6.0437159056137599999e-02"),
|
||||
};
|
||||
static const mpfr::mpreal Q2[] = {
|
||||
static_cast<mpfr::mpreal>("3.7510433111922824643e-05"),
|
||||
static_cast<mpfr::mpreal>("-2.2835624489492512649e-03"),
|
||||
static_cast<mpfr::mpreal>("7.4212010813186530069e-02"),
|
||||
static_cast<mpfr::mpreal>("-8.5017476463217924408e-01"),
|
||||
static_cast<mpfr::mpreal>("3.2593714889036996297e+00"),
|
||||
static_cast<mpfr::mpreal>("-3.8806586721556593450e+00"),
|
||||
static_cast<mpfr::mpreal>("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<mpfr::mpreal>(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
|
||||
|
||||
876
third-party/boost-math/include/boost/math/bindings/rr.hpp
vendored
Normal file
876
third-party/boost-math/include/boost/math/bindings/rr.hpp
vendored
Normal file
@ -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 <boost/math/tools/real_cast.hpp>
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/tools/roots.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/bindings/detail/big_digamma.hpp>
|
||||
#include <boost/math/bindings/detail/big_lanczos.hpp>
|
||||
#include <stdexcept>
|
||||
#include <ostream>
|
||||
#include <istream>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <NTL/RR.h>
|
||||
|
||||
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 <class V>
|
||||
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 <class V>
|
||||
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<double>(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 <class T>
|
||||
inline bool operator == (const T& a, const RR& b)
|
||||
{
|
||||
return a == b.value();
|
||||
}
|
||||
template <class T>
|
||||
inline bool operator != (const T& a, const RR& b)
|
||||
{
|
||||
return a != b.value();
|
||||
}
|
||||
template <class T>
|
||||
inline bool operator < (const T& a, const RR& b)
|
||||
{
|
||||
return a < b.value();
|
||||
}
|
||||
template <class T>
|
||||
inline bool operator > (const T& a, const RR& b)
|
||||
{
|
||||
return a > b.value();
|
||||
}
|
||||
template <class T>
|
||||
inline bool operator <= (const T& a, const RR& b)
|
||||
{
|
||||
return a <= b.value();
|
||||
}
|
||||
template <class T>
|
||||
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 <class charT, class traits>
|
||||
inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const RR& a)
|
||||
{
|
||||
return os << a.value();
|
||||
}
|
||||
template <class charT, class traits>
|
||||
inline std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& 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<class Policy>
|
||||
struct lanczos<ntl::RR, Policy>
|
||||
{
|
||||
typedef ntl_lanczos type;
|
||||
};
|
||||
|
||||
} // namespace lanczos
|
||||
|
||||
namespace tools
|
||||
{
|
||||
|
||||
template<>
|
||||
inline int digits<boost::math::ntl::RR>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR))
|
||||
{
|
||||
return ::NTL::RR::precision();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float real_cast<float, boost::math::ntl::RR>(boost::math::ntl::RR t)
|
||||
{
|
||||
double r;
|
||||
conv(r, t.value());
|
||||
return static_cast<float>(r);
|
||||
}
|
||||
template <>
|
||||
inline double real_cast<double, boost::math::ntl::RR>(boost::math::ntl::RR t)
|
||||
{
|
||||
double r;
|
||||
conv(r, t.value());
|
||||
return r;
|
||||
}
|
||||
|
||||
namespace detail{
|
||||
|
||||
template<class Integer>
|
||||
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<I>(term);
|
||||
t -= term;
|
||||
}while(result != last_result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
inline long double real_cast<long double, boost::math::ntl::RR>(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, boost::math::ntl::RR>(boost::math::ntl::RR t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
template <>
|
||||
inline unsigned real_cast<unsigned, boost::math::ntl::RR>(boost::math::ntl::RR t)
|
||||
{
|
||||
unsigned result;
|
||||
detail::convert_to_long_result(t.value(), result);
|
||||
return result;
|
||||
}
|
||||
template <>
|
||||
inline int real_cast<int, boost::math::ntl::RR>(boost::math::ntl::RR t)
|
||||
{
|
||||
int result;
|
||||
detail::convert_to_long_result(t.value(), result);
|
||||
return result;
|
||||
}
|
||||
template <>
|
||||
inline long real_cast<long, boost::math::ntl::RR>(boost::math::ntl::RR t)
|
||||
{
|
||||
long result;
|
||||
detail::convert_to_long_result(t.value(), result);
|
||||
return result;
|
||||
}
|
||||
template <>
|
||||
inline long long real_cast<long long, boost::math::ntl::RR>(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::ntl::RR>(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::ntl::RR>(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::ntl::RR>(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::ntl::RR>(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::ntl::RR>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR))
|
||||
{
|
||||
return ldexp(boost::math::ntl::RR(1), 1-boost::math::policies::digits<boost::math::ntl::RR, boost::math::policies::policy<> >());
|
||||
}
|
||||
|
||||
} // 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::ntl::RR>(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::ntl::RR>(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<RR, RR, RR> 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<RR>()/2),
|
||||
RR(boost::math::constants::pi<RR>()/2),
|
||||
NTL::RR::precision());
|
||||
}
|
||||
|
||||
struct acos_root
|
||||
{
|
||||
acos_root(RR const& target) : t(target){}
|
||||
|
||||
boost::math::tuple<RR, RR, RR> 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<RR>()/2),
|
||||
RR(boost::math::constants::pi<RR>()/2),
|
||||
NTL::RR::precision());
|
||||
}
|
||||
|
||||
struct atan_root
|
||||
{
|
||||
atan_root(RR const& target) : t(target){}
|
||||
|
||||
boost::math::tuple<RR, RR, RR> 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<RR>()/2,
|
||||
boost::math::constants::pi<RR>()/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<RR>() : atan(y / x) + boost::math::constants::pi<RR>();
|
||||
}
|
||||
return y < 0 ? -boost::math::constants::half_pi<RR>() : boost::math::constants::half_pi<RR>() ;
|
||||
}
|
||||
|
||||
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 <class Policy>
|
||||
inline int iround(RR const& x, const Policy& pol)
|
||||
{
|
||||
return tools::real_cast<int>(round(x, pol));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long lround(RR const& x, const Policy& pol)
|
||||
{
|
||||
return tools::real_cast<long>(round(x, pol));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long long llround(RR const& x, const Policy& pol)
|
||||
{
|
||||
return tools::real_cast<long long>(round(x, pol));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline int itrunc(RR const& x, const Policy& pol)
|
||||
{
|
||||
return tools::real_cast<int>(trunc(x, pol));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long ltrunc(RR const& x, const Policy& pol)
|
||||
{
|
||||
return tools::real_cast<long>(trunc(x, pol));
|
||||
}
|
||||
|
||||
template <class Policy>
|
||||
inline long long lltrunc(RR const& x, const Policy& pol)
|
||||
{
|
||||
return tools::real_cast<long long>(trunc(x, pol));
|
||||
}
|
||||
|
||||
} // namespace ntl
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <class Policy>
|
||||
ntl::RR digamma_imp(ntl::RR x, const std::integral_constant<int, 0>* , 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<ntl::RR>("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol);
|
||||
}
|
||||
result = constants::pi<ntl::RR>() / tan(constants::pi<ntl::RR>() * remainder);
|
||||
}
|
||||
result += big_digamma(x);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_MATH_REAL_CONCEPT_HPP
|
||||
|
||||
|
||||
89
third-party/boost-math/include/boost/math/ccmath/abs.hpp
vendored
Normal file
89
third-party/boost-math/include/boost/math/ccmath/abs.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/abs.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
constexpr T abs_impl(T x) noexcept
|
||||
{
|
||||
if ((boost::math::ccmath::isnan)(x))
|
||||
{
|
||||
return std::numeric_limits<T>::quiet_NaN();
|
||||
}
|
||||
else if (x == static_cast<T>(-0))
|
||||
{
|
||||
return static_cast<T>(0);
|
||||
}
|
||||
|
||||
if constexpr (std::is_integral_v<T>)
|
||||
{
|
||||
BOOST_MATH_ASSERT(x != (std::numeric_limits<T>::min)());
|
||||
}
|
||||
|
||||
return x >= 0 ? x : -x;
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename T, std::enable_if_t<!std::is_unsigned_v<T>, bool> = true>
|
||||
constexpr T abs(T x) noexcept
|
||||
{
|
||||
if(BOOST_MATH_IS_CONSTANT_EVALUATED(x))
|
||||
{
|
||||
return detail::abs_impl<T>(x);
|
||||
}
|
||||
else
|
||||
{
|
||||
using std::abs;
|
||||
return abs(x);
|
||||
}
|
||||
}
|
||||
|
||||
// If abs() is called with an argument of type X for which is_unsigned_v<X> is true and if X
|
||||
// cannot be converted to int by integral promotion (7.3.7), the program is ill-formed.
|
||||
template <typename T, std::enable_if_t<std::is_unsigned_v<T>, bool> = true>
|
||||
constexpr T abs(T x) noexcept
|
||||
{
|
||||
if constexpr (std::is_convertible_v<T, int>)
|
||||
{
|
||||
return detail::abs_impl<int>(static_cast<int>(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
|
||||
45
third-party/boost-math/include/boost/math/ccmath/ccmath.hpp
vendored
Normal file
45
third-party/boost-math/include/boost/math/ccmath/ccmath.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/sqrt.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/fabs.hpp>
|
||||
#include <boost/math/ccmath/isfinite.hpp>
|
||||
#include <boost/math/ccmath/isnormal.hpp>
|
||||
#include <boost/math/ccmath/fpclassify.hpp>
|
||||
#include <boost/math/ccmath/frexp.hpp>
|
||||
#include <boost/math/ccmath/div.hpp>
|
||||
#include <boost/math/ccmath/logb.hpp>
|
||||
#include <boost/math/ccmath/ilogb.hpp>
|
||||
#include <boost/math/ccmath/scalbn.hpp>
|
||||
#include <boost/math/ccmath/scalbln.hpp>
|
||||
#include <boost/math/ccmath/floor.hpp>
|
||||
#include <boost/math/ccmath/ceil.hpp>
|
||||
#include <boost/math/ccmath/trunc.hpp>
|
||||
#include <boost/math/ccmath/modf.hpp>
|
||||
#include <boost/math/ccmath/round.hpp>
|
||||
#include <boost/math/ccmath/fmod.hpp>
|
||||
#include <boost/math/ccmath/remainder.hpp>
|
||||
#include <boost/math/ccmath/copysign.hpp>
|
||||
#include <boost/math/ccmath/hypot.hpp>
|
||||
#include <boost/math/ccmath/fdim.hpp>
|
||||
#include <boost/math/ccmath/fmax.hpp>
|
||||
#include <boost/math/ccmath/fmin.hpp>
|
||||
#include <boost/math/ccmath/isgreater.hpp>
|
||||
#include <boost/math/ccmath/isgreaterequal.hpp>
|
||||
#include <boost/math/ccmath/isless.hpp>
|
||||
#include <boost/math/ccmath/islessequal.hpp>
|
||||
#include <boost/math/ccmath/isunordered.hpp>
|
||||
#include <boost/math/ccmath/fma.hpp>
|
||||
#include <boost/math/ccmath/next.hpp>
|
||||
#include <boost/math/ccmath/signbit.hpp>
|
||||
|
||||
#endif // BOOST_MATH_CCMATH_HPP
|
||||
78
third-party/boost-math/include/boost/math/ccmath/ceil.hpp
vendored
Normal file
78
third-party/boost-math/include/boost/math/ccmath/ceil.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/ceil.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/floor.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
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 <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr double ceil(Z arg) noexcept
|
||||
{
|
||||
return boost::math::ccmath::ceil(static_cast<double>(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
|
||||
81
third-party/boost-math/include/boost/math/ccmath/copysign.hpp
vendored
Normal file
81
third-party/boost-math/include/boost/math/ccmath/copysign.hpp
vendored
Normal file
@ -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 <cmath>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
#include <boost/math/tools/is_constant_evaluated.hpp>
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/signbit.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
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 <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename T1, typename T2>
|
||||
constexpr auto copysign(T1 mag, T2 sgn) noexcept
|
||||
{
|
||||
if (BOOST_MATH_IS_CONSTANT_EVALUATED(mag))
|
||||
{
|
||||
using promoted_type = boost::math::tools::promote_args_t<T1, T2>;
|
||||
return boost::math::ccmath::copysign(static_cast<promoted_type>(mag), static_cast<promoted_type>(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
|
||||
52
third-party/boost-math/include/boost/math/ccmath/detail/config.hpp
vendored
Normal file
52
third-party/boost-math/include/boost/math/ccmath/detail/config.hpp
vendored
Normal file
@ -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 <cmath>
|
||||
#include <type_traits>
|
||||
#include <limits>
|
||||
#include <boost/math/tools/is_constant_evaluated.hpp>
|
||||
#include <boost/math/tools/is_standalone.hpp>
|
||||
|
||||
#ifndef BOOST_MATH_STANDALONE
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#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 <type_traits>
|
||||
//
|
||||
#if (defined(__cpp_lib_bool_constant) && __cpp_lib_bool_constant < 201505L) && !defined(BOOST_MATH_NO_CCMATH)
|
||||
# define BOOST_MATH_NO_CCMATH
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
21
third-party/boost-math/include/boost/math/ccmath/detail/swap.hpp
vendored
Normal file
21
third-party/boost-math/include/boost/math/ccmath/detail/swap.hpp
vendored
Normal file
@ -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 <typename T>
|
||||
inline constexpr void swap(T& x, T& y) noexcept
|
||||
{
|
||||
T temp = x;
|
||||
x = y;
|
||||
y = temp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_MATH_CCMATH_DETAIL_SWAP_HPP
|
||||
86
third-party/boost-math/include/boost/math/ccmath/div.hpp
vendored
Normal file
86
third-party/boost-math/include/boost/math/ccmath/div.hpp
vendored
Normal file
@ -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 <cinttypes>
|
||||
#include <cstdint>
|
||||
#include <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/div.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename ReturnType, typename Z>
|
||||
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 <typename Z>
|
||||
struct div_t
|
||||
{
|
||||
Z quot;
|
||||
Z rem;
|
||||
};
|
||||
|
||||
template <typename Z>
|
||||
inline constexpr auto div(Z x, Z y) noexcept
|
||||
{
|
||||
if constexpr (std::is_same_v<Z, int>)
|
||||
{
|
||||
return detail::div_impl<std::div_t>(x, y);
|
||||
}
|
||||
else if constexpr (std::is_same_v<Z, long>)
|
||||
{
|
||||
return detail::div_impl<std::ldiv_t>(x, y);
|
||||
}
|
||||
else if constexpr (std::is_same_v<Z, long long>)
|
||||
{
|
||||
return detail::div_impl<std::lldiv_t>(x, y);
|
||||
}
|
||||
else if constexpr (std::is_same_v<Z, std::intmax_t>)
|
||||
{
|
||||
return detail::div_impl<std::imaxdiv_t>(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
return detail::div_impl<boost::math::ccmath::div_t<Z>>(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
inline constexpr std::ldiv_t ldiv(long x, long y) noexcept
|
||||
{
|
||||
return detail::div_impl<std::ldiv_t>(x, y);
|
||||
}
|
||||
|
||||
inline constexpr std::lldiv_t lldiv(long long x, long long y) noexcept
|
||||
{
|
||||
return detail::div_impl<std::lldiv_t>(x, y);
|
||||
}
|
||||
|
||||
inline constexpr std::imaxdiv_t imaxdiv(std::intmax_t x, std::intmax_t y) noexcept
|
||||
{
|
||||
return detail::div_impl<std::imaxdiv_t>(x, y);
|
||||
}
|
||||
|
||||
} // Namespaces
|
||||
|
||||
#endif // BOOST_MATH_CCMATH_DIV_HPP
|
||||
41
third-party/boost-math/include/boost/math/ccmath/fabs.hpp
vendored
Normal file
41
third-party/boost-math/include/boost/math/ccmath/fabs.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/fabs.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T>
|
||||
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
|
||||
93
third-party/boost-math/include/boost/math/ccmath/fdim.hpp
vendored
Normal file
93
third-party/boost-math/include/boost/math/ccmath/fdim.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/fdim.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
constexpr T fdim_impl(const T x, const T y) noexcept
|
||||
{
|
||||
if (x <= y)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if ((y < 0) && (x > (std::numeric_limits<T>::max)() + y))
|
||||
{
|
||||
return std::numeric_limits<T>::infinity();
|
||||
}
|
||||
else
|
||||
{
|
||||
return x - y;
|
||||
}
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename T1, typename T2>
|
||||
constexpr auto fdim(T1 x, T2 y) noexcept
|
||||
{
|
||||
if (BOOST_MATH_IS_CONSTANT_EVALUATED(x))
|
||||
{
|
||||
using promoted_type = boost::math::tools::promote_args_t<T1, T2>;
|
||||
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
|
||||
131
third-party/boost-math/include/boost/math/ccmath/floor.hpp
vendored
Normal file
131
third-party/boost-math/include/boost/math/ccmath/floor.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/floor.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
inline constexpr T floor_pos_impl(T arg) noexcept
|
||||
{
|
||||
constexpr auto max_comp_val = T(1) / std::numeric_limits<T>::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 <typename T>
|
||||
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 <typename T>
|
||||
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 <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr double floor(Z arg) noexcept
|
||||
{
|
||||
return boost::math::ccmath::floor(static_cast<double>(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
|
||||
130
third-party/boost-math/include/boost/math/ccmath/fma.hpp
vendored
Normal file
130
third-party/boost-math/include/boost/math/ccmath/fma.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/fma.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
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<T, float>)
|
||||
{
|
||||
return __builtin_fmaf(x, y, z);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, double>)
|
||||
{
|
||||
return __builtin_fma(x, y, z);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, long double>)
|
||||
{
|
||||
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 <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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<Real>::quiet_NaN();
|
||||
}
|
||||
else if (y == 0 && boost::math::ccmath::isinf(x))
|
||||
{
|
||||
return std::numeric_limits<Real>::quiet_NaN();
|
||||
}
|
||||
else if (boost::math::ccmath::isnan(x))
|
||||
{
|
||||
return std::numeric_limits<Real>::quiet_NaN();
|
||||
}
|
||||
else if (boost::math::ccmath::isnan(y))
|
||||
{
|
||||
return std::numeric_limits<Real>::quiet_NaN();
|
||||
}
|
||||
else if (boost::math::ccmath::isnan(z))
|
||||
{
|
||||
return std::numeric_limits<Real>::quiet_NaN();
|
||||
}
|
||||
|
||||
return boost::math::ccmath::detail::fma_imp(x, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
using std::fma;
|
||||
return fma(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1, typename T2, typename T3>
|
||||
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<T1>::epsilon() > 0 ? std::numeric_limits<T1>::epsilon() : 1;
|
||||
constexpr auto T2p = std::numeric_limits<T2>::epsilon() > 0 ? std::numeric_limits<T2>::epsilon() : 1;
|
||||
constexpr auto T3p = std::numeric_limits<T3>::epsilon() > 0 ? std::numeric_limits<T3>::epsilon() : 1;
|
||||
|
||||
using promoted_type =
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
std::conditional_t<T1p <= LDBL_EPSILON && T1p <= T2p, T1,
|
||||
std::conditional_t<T2p <= LDBL_EPSILON && T2p <= T1p, T2,
|
||||
std::conditional_t<T3p <= LDBL_EPSILON && T3p <= T2p, T3,
|
||||
#endif
|
||||
std::conditional_t<T1p <= DBL_EPSILON && T1p <= T2p, T1,
|
||||
std::conditional_t<T2p <= DBL_EPSILON && T2p <= T1p, T2,
|
||||
std::conditional_t<T3p <= DBL_EPSILON && T3p <= T2p, T3, double
|
||||
#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
|
||||
>>>>>>;
|
||||
#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
|
||||
89
third-party/boost-math/include/boost/math/ccmath/fmax.hpp
vendored
Normal file
89
third-party/boost-math/include/boost/math/ccmath/fmax.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/fmax.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
constexpr T fmax_impl(const T x, const T y) noexcept
|
||||
{
|
||||
if (x > y)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
else
|
||||
{
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename T1, typename T2>
|
||||
constexpr auto fmax(T1 x, T2 y) noexcept
|
||||
{
|
||||
if (BOOST_MATH_IS_CONSTANT_EVALUATED(x))
|
||||
{
|
||||
using promoted_type = boost::math::tools::promote_args_t<T1, T2>;
|
||||
return boost::math::ccmath::fmax(static_cast<promoted_type>(x), static_cast<promoted_type>(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
|
||||
89
third-party/boost-math/include/boost/math/ccmath/fmin.hpp
vendored
Normal file
89
third-party/boost-math/include/boost/math/ccmath/fmin.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/fmin.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
constexpr T fmin_impl(const T x, const T y) noexcept
|
||||
{
|
||||
if (x < y)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
else
|
||||
{
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename T1, typename T2>
|
||||
constexpr auto fmin(T1 x, T2 y) noexcept
|
||||
{
|
||||
if (BOOST_MATH_IS_CONSTANT_EVALUATED(x))
|
||||
{
|
||||
using promoted_type = boost::math::tools::promote_args_t<T1, T2>;
|
||||
return boost::math::ccmath::fmin(static_cast<promoted_type>(x), static_cast<promoted_type>(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
|
||||
114
third-party/boost-math/include/boost/math/ccmath/fmod.hpp
vendored
Normal file
114
third-party/boost-math/include/boost/math/ccmath/fmod.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/fmod.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/isfinite.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
constexpr T fmod_impl(T x, T y)
|
||||
{
|
||||
if (x == y)
|
||||
{
|
||||
return static_cast<T>(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (x >= y)
|
||||
{
|
||||
x -= y;
|
||||
}
|
||||
|
||||
return static_cast<T>(x);
|
||||
}
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, bool> = true>
|
||||
constexpr Real fmod(Real x, Real y)
|
||||
{
|
||||
if(BOOST_MATH_IS_CONSTANT_EVALUATED(x))
|
||||
{
|
||||
if (boost::math::ccmath::abs(x) == static_cast<Real>(0) && y != static_cast<Real>(0))
|
||||
{
|
||||
return x;
|
||||
}
|
||||
else if (boost::math::ccmath::isinf(x) && !boost::math::ccmath::isnan(y))
|
||||
{
|
||||
return std::numeric_limits<Real>::quiet_NaN();
|
||||
}
|
||||
else if (boost::math::ccmath::abs(y) == static_cast<Real>(0) && !boost::math::ccmath::isnan(x))
|
||||
{
|
||||
return std::numeric_limits<Real>::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<Real>(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
using std::fmod;
|
||||
return fmod(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
constexpr auto fmod(T1 x, T2 y)
|
||||
{
|
||||
if(BOOST_MATH_IS_CONSTANT_EVALUATED(x))
|
||||
{
|
||||
using promoted_type = boost::math::tools::promote_args_t<T1, T2>;
|
||||
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
|
||||
48
third-party/boost-math/include/boost/math/ccmath/fpclassify.hpp
vendored
Normal file
48
third-party/boost-math/include/boost/math/ccmath/fpclassify.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/fpclassify.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/isfinite.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T, std::enable_if_t<!std::is_integral_v<T>, 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<T>::min)() ? FP_SUBNORMAL : FP_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
using boost::math::fpclassify;
|
||||
return (fpclassify)(x);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr int fpclassify(Z x)
|
||||
{
|
||||
return boost::math::ccmath::fpclassify(static_cast<double>(x));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_MATH_CCMATH_FPCLASSIFY
|
||||
101
third-party/boost-math/include/boost/math/ccmath/frexp.hpp
vendored
Normal file
101
third-party/boost-math/include/boost/math/ccmath/frexp.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/frexp.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/isfinite.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <typename Real>
|
||||
inline constexpr Real frexp_zero_impl(Real arg, int* exp)
|
||||
{
|
||||
*exp = 0;
|
||||
return arg;
|
||||
}
|
||||
|
||||
template <typename Real>
|
||||
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 <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr double frexp(Z arg, int* exp)
|
||||
{
|
||||
return boost::math::ccmath::frexp(static_cast<double>(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
|
||||
116
third-party/boost-math/include/boost/math/ccmath/hypot.hpp
vendored
Normal file
116
third-party/boost-math/include/boost/math/ccmath/hypot.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/hypot.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/ccmath/sqrt.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/detail/swap.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
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<T>::epsilon() >= y)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
T rat = y / x;
|
||||
return x * boost::math::ccmath::sqrt(1 + rat * rat);
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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<Real>(0))
|
||||
{
|
||||
return boost::math::ccmath::abs(y);
|
||||
}
|
||||
else if (boost::math::ccmath::abs(y) == static_cast<Real>(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<Real>::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 <typename T1, typename T2>
|
||||
constexpr auto hypot(T1 x, T2 y) noexcept
|
||||
{
|
||||
if(BOOST_MATH_IS_CONSTANT_EVALUATED(x))
|
||||
{
|
||||
using promoted_type = boost::math::tools::promote_args_t<T1, T2>;
|
||||
return boost::math::ccmath::hypot(static_cast<promoted_type>(x), static_cast<promoted_type>(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
|
||||
60
third-party/boost-math/include/boost/math/ccmath/ilogb.hpp
vendored
Normal file
60
third-party/boost-math/include/boost/math/ccmath/ilogb.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/ilogb.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/logb.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
// If arg is not zero, infinite, or NaN, the value returned is exactly equivalent to static_cast<int>(std::logb(arg))
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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<int>(boost::math::ccmath::logb(arg));
|
||||
}
|
||||
else
|
||||
{
|
||||
using std::ilogb;
|
||||
return ilogb(arg);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr int ilogb(Z arg) noexcept
|
||||
{
|
||||
return boost::math::ccmath::ilogb(static_cast<double>(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
|
||||
53
third-party/boost-math/include/boost/math/ccmath/isfinite.hpp
vendored
Normal file
53
third-party/boost-math/include/boost/math/ccmath/isfinite.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/isfinite.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T>
|
||||
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<double>(arg))
|
||||
if constexpr (std::is_integral_v<T>)
|
||||
{
|
||||
return !boost::math::ccmath::isinf(static_cast<double>(x)) && !boost::math::ccmath::isnan(static_cast<double>(x));
|
||||
}
|
||||
else
|
||||
{
|
||||
return !boost::math::ccmath::isinf(x) && !boost::math::ccmath::isnan(x);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using std::isfinite;
|
||||
|
||||
if constexpr (!std::is_integral_v<T>)
|
||||
{
|
||||
return isfinite(x);
|
||||
}
|
||||
else
|
||||
{
|
||||
return isfinite(static_cast<double>(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_MATH_CCMATH_ISFINITE
|
||||
42
third-party/boost-math/include/boost/math/ccmath/isgreater.hpp
vendored
Normal file
42
third-party/boost-math/include/boost/math/ccmath/isgreater.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/isgreater.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T1, typename T2 = T1>
|
||||
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
|
||||
42
third-party/boost-math/include/boost/math/ccmath/isgreaterequal.hpp
vendored
Normal file
42
third-party/boost-math/include/boost/math/ccmath/isgreaterequal.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/islessequal.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T1, typename T2 = T1>
|
||||
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
|
||||
61
third-party/boost-math/include/boost/math/ccmath/isinf.hpp
vendored
Normal file
61
third-party/boost-math/include/boost/math/ccmath/isinf.hpp
vendored
Normal file
@ -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 <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/isinf.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T>
|
||||
constexpr bool isinf BOOST_MATH_PREVENT_MACRO_SUBSTITUTION(T x) noexcept
|
||||
{
|
||||
if(BOOST_MATH_IS_CONSTANT_EVALUATED(x))
|
||||
{
|
||||
if constexpr (std::numeric_limits<T>::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<T>::infinity() || -x == std::numeric_limits<T>::infinity();
|
||||
#if defined(__clang_major__) && __clang_major__ >= 6
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return x == std::numeric_limits<T>::infinity();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using boost::math::isinf;
|
||||
|
||||
if constexpr (!std::is_integral_v<T>)
|
||||
{
|
||||
return (isinf)(x);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (isinf)(static_cast<double>(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_MATH_CCMATH_ISINF
|
||||
42
third-party/boost-math/include/boost/math/ccmath/isless.hpp
vendored
Normal file
42
third-party/boost-math/include/boost/math/ccmath/isless.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/isless.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T1, typename T2 = T1>
|
||||
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
|
||||
42
third-party/boost-math/include/boost/math/ccmath/islessequal.hpp
vendored
Normal file
42
third-party/boost-math/include/boost/math/ccmath/islessequal.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/islessequal.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T1, typename T2 = T1>
|
||||
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
|
||||
42
third-party/boost-math/include/boost/math/ccmath/isnan.hpp
vendored
Normal file
42
third-party/boost-math/include/boost/math/ccmath/isnan.hpp
vendored
Normal file
@ -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 <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/isnan.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T>
|
||||
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<T>)
|
||||
{
|
||||
return (isnan)(x);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (isnan)(static_cast<double>(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_MATH_CCMATH_ISNAN
|
||||
47
third-party/boost-math/include/boost/math/ccmath/isnormal.hpp
vendored
Normal file
47
third-party/boost-math/include/boost/math/ccmath/isnormal.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/isnormal.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T>
|
||||
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<T>::min)() ? false : true;
|
||||
}
|
||||
else
|
||||
{
|
||||
using std::isnormal;
|
||||
|
||||
if constexpr (!std::is_integral_v<T>)
|
||||
{
|
||||
return isnormal(x);
|
||||
}
|
||||
else
|
||||
{
|
||||
return isnormal(static_cast<double>(x));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_MATH_ISNORMAL_HPP
|
||||
35
third-party/boost-math/include/boost/math/ccmath/isunordered.hpp
vendored
Normal file
35
third-party/boost-math/include/boost/math/ccmath/isunordered.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/isunordered.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename T>
|
||||
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
|
||||
81
third-party/boost-math/include/boost/math/ccmath/ldexp.hpp
vendored
Normal file
81
third-party/boost-math/include/boost/math/ccmath/ldexp.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/ldexp.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Real>
|
||||
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 <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr double ldexp(Z arg, int exp) noexcept
|
||||
{
|
||||
return boost::math::ccmath::ldexp(static_cast<double>(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
|
||||
86
third-party/boost-math/include/boost/math/ccmath/logb.hpp
vendored
Normal file
86
third-party/boost-math/include/boost/math/ccmath/logb.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/logb.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/frexp.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
|
||||
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 <typename T>
|
||||
constexpr T logb_impl(T arg) noexcept
|
||||
{
|
||||
int exp = 0;
|
||||
boost::math::ccmath::frexp(arg, &exp);
|
||||
|
||||
return static_cast<T>(exp - 1);
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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<Real>::infinity();
|
||||
}
|
||||
else if (boost::math::ccmath::isinf(arg))
|
||||
{
|
||||
return std::numeric_limits<Real>::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 <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
constexpr double logb(Z arg) noexcept
|
||||
{
|
||||
return boost::math::ccmath::logb(static_cast<double>(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
|
||||
79
third-party/boost-math/include/boost/math/ccmath/modf.hpp
vendored
Normal file
79
third-party/boost-math/include/boost/math/ccmath/modf.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/modf.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/trunc.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Real>
|
||||
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 <typename Real>
|
||||
inline constexpr Real modf_nan_impl(Real x, Real* iptr)
|
||||
{
|
||||
*iptr = x;
|
||||
return x;
|
||||
}
|
||||
|
||||
template <typename Real>
|
||||
inline constexpr Real modf_impl(Real x, Real* iptr)
|
||||
{
|
||||
*iptr = boost::math::ccmath::trunc(x);
|
||||
return (x - *iptr);
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real>
|
||||
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
|
||||
458
third-party/boost-math/include/boost/math/ccmath/next.hpp
vendored
Normal file
458
third-party/boost-math/include/boost/math/ccmath/next.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/next.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cfloat>
|
||||
#include <cstdint>
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
#include <boost/math/tools/traits.hpp>
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/ccmath/ilogb.hpp>
|
||||
#include <boost/math/ccmath/ldexp.hpp>
|
||||
#include <boost/math/ccmath/scalbln.hpp>
|
||||
#include <boost/math/ccmath/round.hpp>
|
||||
#include <boost/math/ccmath/fabs.hpp>
|
||||
#include <boost/math/ccmath/fpclassify.hpp>
|
||||
#include <boost/math/ccmath/isfinite.hpp>
|
||||
#include <boost/math/ccmath/fmod.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Forward Declarations
|
||||
template <typename T, typename result_type = tools::promote_args_t<T>>
|
||||
constexpr result_type float_prior(const T& val);
|
||||
|
||||
template <typename T, typename result_type = tools::promote_args_t<T>>
|
||||
constexpr result_type float_next(const T& val);
|
||||
|
||||
template <typename T>
|
||||
struct has_hidden_guard_digits;
|
||||
template <>
|
||||
struct has_hidden_guard_digits<float> : public std::false_type {};
|
||||
template <>
|
||||
struct has_hidden_guard_digits<double> : public std::false_type {};
|
||||
template <>
|
||||
struct has_hidden_guard_digits<long double> : public std::false_type {};
|
||||
#ifdef BOOST_HAS_FLOAT128
|
||||
template <>
|
||||
struct has_hidden_guard_digits<__float128> : public std::false_type {};
|
||||
#endif
|
||||
|
||||
template <typename T, bool b>
|
||||
struct has_hidden_guard_digits_10 : public std::false_type {};
|
||||
template <typename T>
|
||||
struct has_hidden_guard_digits_10<T, true> : public std::integral_constant<bool, (std::numeric_limits<T>::digits10 != std::numeric_limits<T>::max_digits10)> {};
|
||||
|
||||
template <typename T>
|
||||
struct has_hidden_guard_digits
|
||||
: public has_hidden_guard_digits_10<T,
|
||||
std::numeric_limits<T>::is_specialized
|
||||
&& (std::numeric_limits<T>::radix == 10) >
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
constexpr T normalize_value(const T& val, const std::false_type&) { return val; }
|
||||
template <typename T>
|
||||
constexpr T normalize_value(const T& val, const std::true_type&)
|
||||
{
|
||||
static_assert(std::numeric_limits<T>::is_specialized, "Type T must be specialized.");
|
||||
static_assert(std::numeric_limits<T>::radix != 2, "Type T must be specialized.");
|
||||
|
||||
std::intmax_t shift = static_cast<std::intmax_t>(std::numeric_limits<T>::digits) - static_cast<std::intmax_t>(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 <typename T>
|
||||
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<T>::denorm_min();
|
||||
return ((tools::min_value<T>() / 2) == 0) ? tools::min_value<T>() : m;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr T get_smallest_value(const std::false_type&)
|
||||
{
|
||||
return tools::min_value<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr T get_smallest_value()
|
||||
{
|
||||
return get_smallest_value<T>(std::integral_constant<bool, std::numeric_limits<T>::is_specialized>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr T calc_min_shifted(const std::true_type&)
|
||||
{
|
||||
return boost::math::ccmath::ldexp(tools::min_value<T>(), tools::digits<T>() + 1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr T calc_min_shifted(const std::false_type&)
|
||||
{
|
||||
static_assert(std::numeric_limits<T>::is_specialized, "Type T must be specialized.");
|
||||
static_assert(std::numeric_limits<T>::radix != 2, "Type T must be specialized.");
|
||||
|
||||
return boost::math::ccmath::scalbn(tools::min_value<T>(), std::numeric_limits<T>::digits + 1);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr T get_min_shift_value()
|
||||
{
|
||||
const T val = calc_min_shifted<T>(std::integral_constant<bool, !std::numeric_limits<T>::is_specialized || std::numeric_limits<T>::radix == 2>());
|
||||
return val;
|
||||
}
|
||||
|
||||
template <typename T, bool b = boost::math::tools::detail::has_backend_type_v<T>>
|
||||
struct exponent_type
|
||||
{
|
||||
using type = int;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct exponent_type<T, true>
|
||||
{
|
||||
using type = typename T::backend_type::exponent_type;
|
||||
};
|
||||
|
||||
template <typename T, bool b = boost::math::tools::detail::has_backend_type_v<T>>
|
||||
using exponent_type_t = typename exponent_type<T>::type;
|
||||
|
||||
template <typename T>
|
||||
constexpr T float_next_imp(const T& val, const std::true_type&)
|
||||
{
|
||||
using exponent_type = exponent_type_t<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<T>())
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
return detail::get_smallest_value<T>();
|
||||
}
|
||||
|
||||
if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO)
|
||||
&& (boost::math::ccmath::fabs(val) < detail::get_min_shift_value<T>())
|
||||
&& (val != -tools::min_value<T>()))
|
||||
{
|
||||
//
|
||||
// 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<T>(boost::math::ccmath::ldexp(val, 2 * tools::digits<T>()))), -2 * tools::digits<T>());
|
||||
}
|
||||
|
||||
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<T>(1), expon - tools::digits<T>());
|
||||
if(diff == 0)
|
||||
{
|
||||
diff = detail::get_smallest_value<T>();
|
||||
}
|
||||
return val + diff;
|
||||
}
|
||||
|
||||
//
|
||||
// Special version for some base other than 2:
|
||||
//
|
||||
template <typename T>
|
||||
constexpr T float_next_imp(const T& val, const std::false_type&)
|
||||
{
|
||||
using exponent_type = exponent_type_t<T>;
|
||||
|
||||
static_assert(std::numeric_limits<T>::is_specialized, "Type T must be specialized.");
|
||||
static_assert(std::numeric_limits<T>::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<T>())
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
return detail::get_smallest_value<T>();
|
||||
}
|
||||
|
||||
if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO)
|
||||
&& (boost::math::ccmath::fabs(val) < detail::get_min_shift_value<T>())
|
||||
&& (val != -tools::min_value<T>()))
|
||||
{
|
||||
//
|
||||
// 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<T>(boost::math::ccmath::scalbn(val, 2 * std::numeric_limits<T>::digits))), -2 * std::numeric_limits<T>::digits);
|
||||
}
|
||||
|
||||
expon = 1 + boost::math::ccmath::ilogb(val);
|
||||
if(-1 == boost::math::ccmath::scalbn(val, -expon) * std::numeric_limits<T>::radix)
|
||||
{
|
||||
--expon; // reduce exponent when val is a power of base, and negative.
|
||||
}
|
||||
|
||||
T diff = boost::math::ccmath::scalbn(static_cast<T>(1), expon - std::numeric_limits<T>::digits);
|
||||
if(diff == 0)
|
||||
{
|
||||
diff = detail::get_smallest_value<T>();
|
||||
}
|
||||
|
||||
return val + diff;
|
||||
}
|
||||
|
||||
template <typename T, typename result_type>
|
||||
constexpr result_type float_next(const T& val)
|
||||
{
|
||||
return detail::float_next_imp(detail::normalize_value(static_cast<result_type>(val), typename detail::has_hidden_guard_digits<result_type>::type()), std::integral_constant<bool, !std::numeric_limits<result_type>::is_specialized || (std::numeric_limits<result_type>::radix == 2)>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr T float_prior_imp(const T& val, const std::true_type&)
|
||||
{
|
||||
using exponent_type = exponent_type_t<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<T>())
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
return -detail::get_smallest_value<T>();
|
||||
}
|
||||
|
||||
if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO)
|
||||
&& (boost::math::ccmath::fabs(val) < detail::get_min_shift_value<T>())
|
||||
&& (val != tools::min_value<T>()))
|
||||
{
|
||||
//
|
||||
// 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<T>(boost::math::ccmath::ldexp(val, 2 * tools::digits<T>()))), -2 * tools::digits<T>());
|
||||
}
|
||||
|
||||
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<T>(1), expon - tools::digits<T>());
|
||||
if(diff == 0)
|
||||
{
|
||||
diff = detail::get_smallest_value<T>();
|
||||
}
|
||||
|
||||
return val - diff;
|
||||
}
|
||||
|
||||
//
|
||||
// Special version for bases other than 2:
|
||||
//
|
||||
template <typename T>
|
||||
constexpr T float_prior_imp(const T& val, const std::false_type&)
|
||||
{
|
||||
using exponent_type = exponent_type_t<T>;
|
||||
|
||||
static_assert(std::numeric_limits<T>::is_specialized, "Type T must be specialized.");
|
||||
static_assert(std::numeric_limits<T>::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<T>())
|
||||
{
|
||||
return val;
|
||||
}
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
return -detail::get_smallest_value<T>();
|
||||
}
|
||||
|
||||
if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO)
|
||||
&& (boost::math::ccmath::fabs(val) < detail::get_min_shift_value<T>())
|
||||
&& (val != tools::min_value<T>()))
|
||||
{
|
||||
//
|
||||
// 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<T>(boost::math::ccmath::scalbn(val, 2 * std::numeric_limits<T>::digits))), -2 * std::numeric_limits<T>::digits);
|
||||
}
|
||||
|
||||
expon = 1 + boost::math::ccmath::ilogb(val);
|
||||
|
||||
if (T remain = boost::math::ccmath::scalbn(val, -expon); remain * std::numeric_limits<T>::radix == 1)
|
||||
{
|
||||
--expon; // when val is a power of two we must reduce the exponent
|
||||
}
|
||||
|
||||
T diff = boost::math::ccmath::scalbn(static_cast<T>(1), expon - std::numeric_limits<T>::digits);
|
||||
if (diff == 0)
|
||||
{
|
||||
diff = detail::get_smallest_value<T>();
|
||||
}
|
||||
return val - diff;
|
||||
} // float_prior_imp
|
||||
|
||||
template <typename T, typename result_type>
|
||||
constexpr result_type float_prior(const T& val)
|
||||
{
|
||||
return detail::float_prior_imp(detail::normalize_value(static_cast<result_type>(val), typename detail::has_hidden_guard_digits<result_type>::type()), std::integral_constant<bool, !std::numeric_limits<result_type>::is_specialized || (std::numeric_limits<result_type>::radix == 2)>());
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename T, typename U, typename result_type = tools::promote_args_t<T, U>>
|
||||
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<result_type>(val), static_cast<result_type>(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 T, typename result_type = tools::promote_args_t<T, long double>, typename return_type = std::conditional_t<std::is_integral_v<T>, double, T>>
|
||||
constexpr return_type nexttoward(T val, long double direction)
|
||||
{
|
||||
if (BOOST_MATH_IS_CONSTANT_EVALUATED(val))
|
||||
{
|
||||
return static_cast<return_type>(boost::math::ccmath::nextafter(static_cast<result_type>(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
|
||||
106
third-party/boost-math/include/boost/math/ccmath/remainder.hpp
vendored
Normal file
106
third-party/boost-math/include/boost/math/ccmath/remainder.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/remainder.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/isfinite.hpp>
|
||||
#include <boost/math/ccmath/modf.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
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<T>(1.0/2))
|
||||
{
|
||||
++n;
|
||||
}
|
||||
else if (fractional_part < static_cast<T>(-1.0/2))
|
||||
{
|
||||
--n;
|
||||
}
|
||||
|
||||
return x - n*y;
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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<Real>::quiet_NaN();
|
||||
}
|
||||
else if (boost::math::ccmath::abs(y) == static_cast<Real>(0) && !boost::math::ccmath::isnan(x))
|
||||
{
|
||||
return std::numeric_limits<Real>::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 <typename T1, typename T2>
|
||||
constexpr auto remainder(T1 x, T2 y)
|
||||
{
|
||||
if (BOOST_MATH_IS_CONSTANT_EVALUATED(x))
|
||||
{
|
||||
using promoted_type = boost::math::tools::promote_args_t<T1, T2>;
|
||||
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
|
||||
179
third-party/boost-math/include/boost/math/ccmath/round.hpp
vendored
Normal file
179
third-party/boost-math/include/boost/math/ccmath/round.hpp
vendored
Normal file
@ -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 <stdexcept>
|
||||
#include <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/round.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/modf.hpp>
|
||||
|
||||
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 <typename T>
|
||||
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 <typename ReturnType, typename T>
|
||||
inline constexpr ReturnType int_round_impl(T arg)
|
||||
{
|
||||
const T rounded_arg = round_impl(arg);
|
||||
|
||||
if(rounded_arg > static_cast<T>((std::numeric_limits<ReturnType>::max)()))
|
||||
{
|
||||
if constexpr (std::is_same_v<ReturnType, long long>)
|
||||
{
|
||||
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<ReturnType>(rounded_arg);
|
||||
}
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr double round(Z arg) noexcept
|
||||
{
|
||||
return boost::math::ccmath::round(static_cast<double>(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 <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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<long>(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
using std::lround;
|
||||
return lround(arg);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr long lround(Z arg)
|
||||
{
|
||||
return boost::math::ccmath::lround(static_cast<double>(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 <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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<long long>(arg);
|
||||
}
|
||||
else
|
||||
{
|
||||
using std::llround;
|
||||
return llround(arg);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr long llround(Z arg)
|
||||
{
|
||||
return boost::math::ccmath::llround(static_cast<double>(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
|
||||
60
third-party/boost-math/include/boost/math/ccmath/scalbln.hpp
vendored
Normal file
60
third-party/boost-math/include/boost/math/ccmath/scalbln.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/scalbln.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <cfloat>
|
||||
#include <boost/math/ccmath/scalbn.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr double scalbln(Z arg, long exp) noexcept
|
||||
{
|
||||
return boost::math::ccmath::scalbln(static_cast<double>(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
|
||||
81
third-party/boost-math/include/boost/math/ccmath/scalbn.hpp
vendored
Normal file
81
third-party/boost-math/include/boost/math/ccmath/scalbn.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/scalbn.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <cfloat>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Real, typename Z>
|
||||
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 <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr double scalbn(Z arg, int exp) noexcept
|
||||
{
|
||||
return boost::math::ccmath::scalbn(static_cast<double>(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
|
||||
219
third-party/boost-math/include/boost/math/ccmath/signbit.hpp
vendored
Normal file
219
third-party/boost-math/include/boost/math/ccmath/signbit.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/signbit.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <cstdint>
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
#include <boost/math/special_functions/detail/fp_traits.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
|
||||
#ifdef __has_include
|
||||
# if __has_include(<bit>)
|
||||
# include <bit>
|
||||
# if __cpp_lib_bit_cast >= 201806L
|
||||
# define BOOST_MATH_BIT_CAST(T, x) std::bit_cast<T>(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 <typename T>
|
||||
constexpr bool signbit_impl(T arg)
|
||||
{
|
||||
if constexpr (std::is_same_v<T, float>)
|
||||
{
|
||||
const auto u = BOOST_MATH_BIT_CAST(IEEEf2bits, arg);
|
||||
return u.sign;
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, double>)
|
||||
{
|
||||
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<T, long double>)
|
||||
{
|
||||
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<T>(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 <typename T>
|
||||
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<T>(0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// Return value: true if arg is negative, false if arg is 0, NAN, or positive
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
constexpr bool signbit(Z arg)
|
||||
{
|
||||
return boost::math::ccmath::signbit(static_cast<double>(arg));
|
||||
}
|
||||
|
||||
} // Namespaces
|
||||
|
||||
#endif // BOOST_MATH_CCMATH_SIGNBIT_HPP
|
||||
80
third-party/boost-math/include/boost/math/ccmath/sqrt.hpp
vendored
Normal file
80
third-party/boost-math/include/boost/math/ccmath/sqrt.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/sqrt.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/tools/is_constant_evaluated.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Real>
|
||||
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 <typename Real>
|
||||
constexpr Real sqrt_impl_1(Real x, Real s)
|
||||
{
|
||||
return sqrt_impl_2(x, (x / s + s) / 2, s);
|
||||
}
|
||||
|
||||
template <typename Real>
|
||||
constexpr Real sqrt_impl(Real x)
|
||||
{
|
||||
return sqrt_impl_1(x, x > 1 ? x : Real(1));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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<Real>::quiet_NaN();
|
||||
}
|
||||
|
||||
return detail::sqrt_impl<Real>(x);
|
||||
}
|
||||
else
|
||||
{
|
||||
using std::sqrt;
|
||||
return sqrt(x);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
constexpr double sqrt(Z x)
|
||||
{
|
||||
return detail::sqrt_impl<double>(static_cast<double>(x));
|
||||
}
|
||||
|
||||
} // Namespaces
|
||||
|
||||
#endif // BOOST_MATH_CCMATH_SQRT
|
||||
70
third-party/boost-math/include/boost/math/ccmath/trunc.hpp
vendored
Normal file
70
third-party/boost-math/include/boost/math/ccmath/trunc.hpp
vendored
Normal file
@ -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 <boost/math/ccmath/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_MATH_NO_CCMATH
|
||||
#error "The header <boost/math/trunc.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
|
||||
#include <boost/math/ccmath/abs.hpp>
|
||||
#include <boost/math/ccmath/isinf.hpp>
|
||||
#include <boost/math/ccmath/isnan.hpp>
|
||||
#include <boost/math/ccmath/floor.hpp>
|
||||
#include <boost/math/ccmath/ceil.hpp>
|
||||
|
||||
namespace boost::math::ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
inline constexpr T trunc_impl(T arg) noexcept
|
||||
{
|
||||
return (arg > 0) ? boost::math::ccmath::floor(arg) : boost::math::ccmath::ceil(arg);
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real, std::enable_if_t<!std::is_integral_v<Real>, 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 <typename Z, std::enable_if_t<std::is_integral_v<Z>, bool> = true>
|
||||
inline constexpr double trunc(Z arg) noexcept
|
||||
{
|
||||
return boost::math::ccmath::trunc(static_cast<double>(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
|
||||
23
third-party/boost-math/include/boost/math/common_factor.hpp
vendored
Normal file
23
third-party/boost-math/include/boost/math/common_factor.hpp
vendored
Normal file
@ -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 <boost/math/common_factor_ct.hpp>
|
||||
#include <boost/math/common_factor_rt.hpp>
|
||||
#include <boost/math/tools/header_deprecated.hpp>
|
||||
|
||||
BOOST_MATH_HEADER_DEPRECATED("<boost/integer/common_factor.hpp>");
|
||||
#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
|
||||
34
third-party/boost-math/include/boost/math/common_factor_ct.hpp
vendored
Normal file
34
third-party/boost-math/include/boost/math/common_factor_ct.hpp
vendored
Normal file
@ -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 <boost/integer/common_factor_ct.hpp>
|
||||
#include <boost/math/tools/header_deprecated.hpp>
|
||||
|
||||
BOOST_MATH_HEADER_DEPRECATED("<boost/integer/common_factor_ct.hpp>");
|
||||
|
||||
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
|
||||
30
third-party/boost-math/include/boost/math/common_factor_rt.hpp
vendored
Normal file
30
third-party/boost-math/include/boost/math/common_factor_rt.hpp
vendored
Normal file
@ -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 <boost/integer/common_factor_rt.hpp>
|
||||
#include <boost/math/tools/header_deprecated.hpp>
|
||||
|
||||
BOOST_MATH_HEADER_DEPRECATED("<boost/integer/common_factor_rt.hpp>");
|
||||
|
||||
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
|
||||
32
third-party/boost-math/include/boost/math/complex.hpp
vendored
Normal file
32
third-party/boost-math/include/boost/math/complex.hpp
vendored
Normal file
@ -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 <boost/math/complex/asin.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_COMPLEX_ASINH_INCLUDED
|
||||
# include <boost/math/complex/asinh.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_COMPLEX_ACOS_INCLUDED
|
||||
# include <boost/math/complex/acos.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_COMPLEX_ACOSH_INCLUDED
|
||||
# include <boost/math/complex/acosh.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_COMPLEX_ATAN_INCLUDED
|
||||
# include <boost/math/complex/atan.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED
|
||||
# include <boost/math/complex/atanh.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_COMPLEX_FABS_INCLUDED
|
||||
# include <boost/math/complex/fabs.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
#endif // BOOST_MATH_COMPLEX_INCLUDED
|
||||
245
third-party/boost-math/include/boost/math/complex/acos.hpp
vendored
Normal file
245
third-party/boost-math/include/boost/math/complex/acos.hpp
vendored
Normal file
@ -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 <boost/math/complex/details.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_LOG1P_INCLUDED
|
||||
# include <boost/math/special_functions/log1p.hpp>
|
||||
#endif
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
|
||||
#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<class T>
|
||||
[[deprecated("Replaced by C++11")]] std::complex<T> acos(const std::complex<T>& 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<T>(1);
|
||||
//static const T two = static_cast<T>(2);
|
||||
static const T half = static_cast<T>(0.5L);
|
||||
static const T a_crossover = static_cast<T>(10);
|
||||
static const T b_crossover = static_cast<T>(0.6417L);
|
||||
static const T s_pi = boost::math::constants::pi<T>();
|
||||
static const T half_pi = s_pi / 2;
|
||||
static const T log_two = boost::math::constants::ln_two<T>();
|
||||
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<T>::infinity();
|
||||
}
|
||||
else if((boost::math::isnan)(y))
|
||||
{
|
||||
return std::complex<T>(y, -std::numeric_limits<T>::infinity());
|
||||
}
|
||||
else
|
||||
{
|
||||
// y is not infinity or nan:
|
||||
real = 0;
|
||||
imag = std::numeric_limits<T>::infinity();
|
||||
}
|
||||
}
|
||||
else if((boost::math::isnan)(x))
|
||||
{
|
||||
if((boost::math::isinf)(y))
|
||||
return std::complex<T>(x, ((boost::math::signbit)(z.imag())) ? std::numeric_limits<T>::infinity() : -std::numeric_limits<T>::infinity());
|
||||
return std::complex<T>(x, x);
|
||||
}
|
||||
else if((boost::math::isinf)(y))
|
||||
{
|
||||
real = half_pi;
|
||||
imag = std::numeric_limits<T>::infinity();
|
||||
}
|
||||
else if((boost::math::isnan)(y))
|
||||
{
|
||||
return std::complex<T>((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<T>((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>.
|
||||
//
|
||||
T safe_max = detail::safe_max(static_cast<T>(8));
|
||||
T safe_min = detail::safe_min(static_cast<T>(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<T>::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<T>::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<T>::epsilon()
|
||||
// u = (std::numeric_limits<T>::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<T>::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<T>(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<T>(real, imag);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
} } // namespaces
|
||||
|
||||
#endif // BOOST_MATH_COMPLEX_ACOS_INCLUDED
|
||||
34
third-party/boost-math/include/boost/math/complex/acosh.hpp
vendored
Normal file
34
third-party/boost-math/include/boost/math/complex/acosh.hpp
vendored
Normal file
@ -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 <boost/math/complex/details.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED
|
||||
# include <boost/math/complex/acos.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template<class T>
|
||||
[[deprecated("Replaced by C++11")]] inline std::complex<T> acosh(const std::complex<T>& 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<T> 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
|
||||
252
third-party/boost-math/include/boost/math/complex/asin.hpp
vendored
Normal file
252
third-party/boost-math/include/boost/math/complex/asin.hpp
vendored
Normal file
@ -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 <boost/math/complex/details.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_LOG1P_INCLUDED
|
||||
# include <boost/math/special_functions/log1p.hpp>
|
||||
#endif
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
|
||||
#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<class T>
|
||||
[[deprecated("Replaced by C++11")]] inline std::complex<T> asin(const std::complex<T>& 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<T>(1);
|
||||
//static const T two = static_cast<T>(2);
|
||||
static const T half = static_cast<T>(0.5L);
|
||||
static const T a_crossover = static_cast<T>(10);
|
||||
static const T b_crossover = static_cast<T>(0.6417L);
|
||||
static const T s_pi = boost::math::constants::pi<T>();
|
||||
static const T half_pi = s_pi / 2;
|
||||
static const T log_two = boost::math::constants::ln_two<T>();
|
||||
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<T>(x, x);
|
||||
if((boost::math::isinf)(y))
|
||||
{
|
||||
real = x;
|
||||
imag = std::numeric_limits<T>::infinity();
|
||||
}
|
||||
else
|
||||
return std::complex<T>(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<T>::infinity();
|
||||
}
|
||||
else
|
||||
return std::complex<T>(y, y);
|
||||
}
|
||||
else if((boost::math::isinf)(x))
|
||||
{
|
||||
if((boost::math::isinf)(y))
|
||||
{
|
||||
real = quarter_pi;
|
||||
imag = std::numeric_limits<T>::infinity();
|
||||
}
|
||||
else
|
||||
{
|
||||
real = half_pi;
|
||||
imag = std::numeric_limits<T>::infinity();
|
||||
}
|
||||
}
|
||||
else if((boost::math::isinf)(y))
|
||||
{
|
||||
real = 0;
|
||||
imag = std::numeric_limits<T>::infinity();
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// special case for real numbers:
|
||||
//
|
||||
if((y == 0) && (x <= one))
|
||||
return std::complex<T>(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>.
|
||||
//
|
||||
T safe_max = detail::safe_max(static_cast<T>(8));
|
||||
T safe_min = detail::safe_min(static_cast<T>(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<T>::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<T>::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<T>::epsilon()
|
||||
// u = (std::numeric_limits<T>::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<T>::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<T>(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<T>(real, imag);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
} } // namespaces
|
||||
|
||||
#endif // BOOST_MATH_COMPLEX_ASIN_INCLUDED
|
||||
32
third-party/boost-math/include/boost/math/complex/asinh.hpp
vendored
Normal file
32
third-party/boost-math/include/boost/math/complex/asinh.hpp
vendored
Normal file
@ -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 <boost/math/complex/details.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_COMPLEX_ASIN_INCLUDED
|
||||
# include <boost/math/complex/asin.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template<class T>
|
||||
[[deprecated("Replaced by C++11")]] inline std::complex<T> asinh(const std::complex<T>& 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
|
||||
36
third-party/boost-math/include/boost/math/complex/atan.hpp
vendored
Normal file
36
third-party/boost-math/include/boost/math/complex/atan.hpp
vendored
Normal file
@ -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 <boost/math/complex/details.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED
|
||||
# include <boost/math/complex/atanh.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template<class T>
|
||||
[[deprecated("Replaced by C++11")]] std::complex<T> atan(const std::complex<T>& x)
|
||||
{
|
||||
//
|
||||
// We're using the C99 definition here; atan(z) = -i atanh(iz):
|
||||
//
|
||||
if(x.real() == 0)
|
||||
{
|
||||
if(x.imag() == 1)
|
||||
return std::complex<T>(0, std::numeric_limits<T>::has_infinity ? std::numeric_limits<T>::infinity() : static_cast<T>(HUGE_VAL));
|
||||
if(x.imag() == -1)
|
||||
return std::complex<T>(0, std::numeric_limits<T>::has_infinity ? -std::numeric_limits<T>::infinity() : -static_cast<T>(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
|
||||
214
third-party/boost-math/include/boost/math/complex/atanh.hpp
vendored
Normal file
214
third-party/boost-math/include/boost/math/complex/atanh.hpp
vendored
Normal file
@ -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 <boost/math/complex/details.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_MATH_LOG1P_INCLUDED
|
||||
# include <boost/math/special_functions/log1p.hpp>
|
||||
#endif
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
|
||||
#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<class T>
|
||||
[[deprecated("Replaced by C++11")]] std::complex<T> atanh(const std::complex<T>& 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<T>();
|
||||
static const T half_pi = pi / 2;
|
||||
static const T one = static_cast<T>(1.0L);
|
||||
static const T two = static_cast<T>(2.0L);
|
||||
static const T four = static_cast<T>(4.0L);
|
||||
static const T zero = static_cast<T>(0);
|
||||
static const T log_two = boost::math::constants::ln_two<T>();
|
||||
|
||||
#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<T>(2));
|
||||
|
||||
//
|
||||
// Begin by handling the special cases specified in C99:
|
||||
//
|
||||
if((boost::math::isnan)(x))
|
||||
{
|
||||
if((boost::math::isnan)(y))
|
||||
return std::complex<T>(x, x);
|
||||
else if((boost::math::isinf)(y))
|
||||
return std::complex<T>(0, ((boost::math::signbit)(z.imag()) ? -half_pi : half_pi));
|
||||
else
|
||||
return std::complex<T>(x, x);
|
||||
}
|
||||
else if((boost::math::isnan)(y))
|
||||
{
|
||||
if(x == 0)
|
||||
return std::complex<T>(x, y);
|
||||
if((boost::math::isinf)(x))
|
||||
return std::complex<T>(0, y);
|
||||
else
|
||||
return std::complex<T>(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<T>(real, imag);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
} } // namespaces
|
||||
|
||||
#endif // BOOST_MATH_COMPLEX_ATANH_INCLUDED
|
||||
68
third-party/boost-math/include/boost/math/complex/details.hpp
vendored
Normal file
68
third-party/boost-math/include/boost/math/complex/details.hpp
vendored
Normal file
@ -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 <cmath>
|
||||
#include <complex>
|
||||
#include <limits>
|
||||
#include <boost/math/special_functions/sign.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class T>
|
||||
inline T mult_minus_one(const T& t)
|
||||
{
|
||||
return (boost::math::isnan)(t) ? t : (boost::math::changesign)(t);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline std::complex<T> mult_i(const std::complex<T>& t)
|
||||
{
|
||||
return std::complex<T>(mult_minus_one(t.imag()), t.real());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline std::complex<T> mult_minus_i(const std::complex<T>& t)
|
||||
{
|
||||
return std::complex<T>(t.imag(), mult_minus_one(t.real()));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T safe_max(T t)
|
||||
{
|
||||
return std::sqrt((std::numeric_limits<T>::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<double>::max)()) / t;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T safe_min(T t)
|
||||
{
|
||||
return std::sqrt((std::numeric_limits<T>::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<double>::min)()) * t;
|
||||
}
|
||||
|
||||
} } } // namespaces
|
||||
|
||||
#endif // BOOST_MATH_COMPLEX_DETAILS_INCLUDED
|
||||
|
||||
23
third-party/boost-math/include/boost/math/complex/fabs.hpp
vendored
Normal file
23
third-party/boost-math/include/boost/math/complex/fabs.hpp
vendored
Normal file
@ -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 <boost/math/special_functions/hypot.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template<class T>
|
||||
inline T fabs(const std::complex<T>& z)
|
||||
{
|
||||
return ::boost::math::hypot(z.real(), z.imag());
|
||||
}
|
||||
|
||||
} } // namespaces
|
||||
|
||||
#endif // BOOST_MATH_COMPLEX_FABS_INCLUDED
|
||||
497
third-party/boost-math/include/boost/math/concepts/distributions.hpp
vendored
Normal file
497
third-party/boost-math/include/boost/math/concepts/distributions.hpp
vendored
Normal file
@ -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 <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#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 <boost/concept_check.hpp>
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#include <utility>
|
||||
|
||||
namespace boost{
|
||||
namespace math{
|
||||
|
||||
namespace concepts
|
||||
{
|
||||
// Begin by defining a concept archetype
|
||||
// for a distribution class:
|
||||
//
|
||||
template <class RealType>
|
||||
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<distribution_archetype*>(nullptr);
|
||||
}
|
||||
}; // template <class RealType>class distribution_archetype
|
||||
|
||||
// Non-member accessor functions:
|
||||
// (This list defines the functions that must be implemented by all distributions).
|
||||
|
||||
template <class RealType>
|
||||
RealType pdf(const distribution_archetype<RealType>& dist, const RealType& x);
|
||||
|
||||
template <class RealType>
|
||||
RealType cdf(const distribution_archetype<RealType>& dist, const RealType& x);
|
||||
|
||||
template <class RealType>
|
||||
RealType quantile(const distribution_archetype<RealType>& dist, const RealType& p);
|
||||
|
||||
template <class RealType>
|
||||
RealType cdf(const complemented2_type<distribution_archetype<RealType>, RealType>& c);
|
||||
|
||||
template <class RealType>
|
||||
RealType quantile(const complemented2_type<distribution_archetype<RealType>, RealType>& c);
|
||||
|
||||
template <class RealType>
|
||||
RealType mean(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
RealType standard_deviation(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
RealType variance(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
RealType hazard(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
RealType chf(const distribution_archetype<RealType>& dist);
|
||||
// http://en.wikipedia.org/wiki/Characteristic_function_%28probability_theory%29
|
||||
|
||||
template <class RealType>
|
||||
RealType coefficient_of_variation(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
RealType mode(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
RealType skewness(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
RealType kurtosis_excess(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
RealType kurtosis(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
RealType median(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
std::pair<RealType, RealType> range(const distribution_archetype<RealType>& dist);
|
||||
|
||||
template <class RealType>
|
||||
std::pair<RealType, RealType> support(const distribution_archetype<RealType>& dist);
|
||||
|
||||
//
|
||||
// Next comes the concept checks for verifying that a class
|
||||
// fulfils the requirements of a Distribution:
|
||||
//
|
||||
template <class Distribution>
|
||||
struct DistributionConcept
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
|
||||
void constraints()
|
||||
{
|
||||
function_requires<CopyConstructibleConcept<Distribution> >();
|
||||
function_requires<AssignableConcept<Distribution> >();
|
||||
|
||||
const Distribution& dist = DistributionConcept<Distribution>::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<value_type, value_type> 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 <class D>
|
||||
static void test_extra_members(const D&)
|
||||
{}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::bernoulli_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.success_fraction();
|
||||
(void)r; // warning suppression
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::beta_distribution<R, P>& d)
|
||||
{
|
||||
value_type r1 = d.alpha();
|
||||
value_type r2 = d.beta();
|
||||
r1 = boost::math::beta_distribution<R, P>::find_alpha(r1, r2);
|
||||
suppress_unused_variable_warning(r1);
|
||||
r1 = boost::math::beta_distribution<R, P>::find_beta(r1, r2);
|
||||
suppress_unused_variable_warning(r1);
|
||||
r1 = boost::math::beta_distribution<R, P>::find_alpha(r1, r2, r1);
|
||||
suppress_unused_variable_warning(r1);
|
||||
r1 = boost::math::beta_distribution<R, P>::find_beta(r1, r2, r1);
|
||||
suppress_unused_variable_warning(r1);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::binomial_distribution<R, P>& 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 <class R, class P>
|
||||
static void test_extra_members(const boost::math::cauchy_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.location();
|
||||
r = d.scale();
|
||||
suppress_unused_variable_warning(r);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::chi_squared_distribution<R, P>& 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 <class R, class P>
|
||||
static void test_extra_members(const boost::math::exponential_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.lambda();
|
||||
suppress_unused_variable_warning(r);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::extreme_value_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.scale();
|
||||
r = d.location();
|
||||
suppress_unused_variable_warning(r);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::fisher_f_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.degrees_of_freedom1();
|
||||
r = d.degrees_of_freedom2();
|
||||
suppress_unused_variable_warning(r);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::gamma_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.scale();
|
||||
r = d.shape();
|
||||
suppress_unused_variable_warning(r);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::inverse_chi_squared_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.scale();
|
||||
r = d.degrees_of_freedom();
|
||||
suppress_unused_variable_warning(r);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::inverse_gamma_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.scale();
|
||||
r = d.shape();
|
||||
suppress_unused_variable_warning(r);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::hypergeometric_distribution<R, P>& d)
|
||||
{
|
||||
std::uint64_t u = d.defective();
|
||||
u = d.sample_count();
|
||||
u = d.total();
|
||||
suppress_unused_variable_warning(u);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::laplace_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.scale();
|
||||
r = d.location();
|
||||
suppress_unused_variable_warning(r);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::logistic_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.scale();
|
||||
r = d.location();
|
||||
suppress_unused_variable_warning(r);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::lognormal_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.scale();
|
||||
r = d.location();
|
||||
suppress_unused_variable_warning(r);
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::negative_binomial_distribution<R, P>& 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 <class R, class P>
|
||||
static void test_extra_members(const boost::math::non_central_beta_distribution<R, P>& d)
|
||||
{
|
||||
value_type r1 = d.alpha();
|
||||
value_type r2 = d.beta();
|
||||
r1 = d.non_centrality();
|
||||
(void)r1; // warning suppression
|
||||
(void)r2; // warning suppression
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::non_central_chi_squared_distribution<R, P>& 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 <class R, class P>
|
||||
static void test_extra_members(const boost::math::non_central_f_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.degrees_of_freedom1();
|
||||
r = d.degrees_of_freedom2();
|
||||
r = d.non_centrality();
|
||||
(void)r; // warning suppression
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::non_central_t_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.degrees_of_freedom();
|
||||
r = d.non_centrality();
|
||||
(void)r; // warning suppression
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::normal_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.scale();
|
||||
r = d.location();
|
||||
r = d.mean();
|
||||
r = d.standard_deviation();
|
||||
(void)r; // warning suppression
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::pareto_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.scale();
|
||||
r = d.shape();
|
||||
(void)r; // warning suppression
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::poisson_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.mean();
|
||||
(void)r; // warning suppression
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::rayleigh_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.sigma();
|
||||
(void)r; // warning suppression
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::students_t_distribution<R, P>& 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 <class R, class P>
|
||||
static void test_extra_members(const boost::math::triangular_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.lower();
|
||||
r = d.mode();
|
||||
r = d.upper();
|
||||
(void)r; // warning suppression
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::weibull_distribution<R, P>& d)
|
||||
{
|
||||
value_type r = d.scale();
|
||||
r = d.shape();
|
||||
(void)r; // warning suppression
|
||||
}
|
||||
template <class R, class P>
|
||||
static void test_extra_members(const boost::math::uniform_distribution<R, P>& 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 <class Distribution>
|
||||
Distribution* DistributionConcept<Distribution>::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
|
||||
|
||||
400
third-party/boost-math/include/boost/math/concepts/real_concept.hpp
vendored
Normal file
400
third-party/boost-math/include/boost/math/concepts/real_concept.hpp
vendored
Normal file
@ -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 <boost/math/special_functions/round.hpp>
|
||||
#include <boost/math/special_functions/trunc.hpp>
|
||||
#include <boost/math/special_functions/modf.hpp>
|
||||
#include <boost/math/tools/big_constant.hpp>
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
#include <boost/math/special_functions/asinh.hpp>
|
||||
#include <boost/math/special_functions/atanh.hpp>
|
||||
#if defined(__SGI_STL_PORT)
|
||||
# include <boost/math/tools/real_cast.hpp>
|
||||
#endif
|
||||
#include <ostream>
|
||||
#include <istream>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(__SGI_STL_PORT) || defined(_RWSTD_VER) || defined(__LIBCOMO__)
|
||||
# include <cstdio>
|
||||
#endif
|
||||
|
||||
#if defined __has_include
|
||||
# if __cplusplus > 202002L || _MSVC_LANG > 202002L
|
||||
# if __has_include (<stdfloat>)
|
||||
# include <stdfloat>
|
||||
# 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<real_concept_base_type>(c)){}
|
||||
real_concept(long long c) : m_value(static_cast<real_concept_base_type>(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<real_concept_base_type>(c)){}
|
||||
#endif
|
||||
#ifdef __STDCPP_FLOAT64_T__
|
||||
real_concept(std::float64_t c) : m_value(static_cast<real_concept_base_type>(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<real_concept_base_type>(c); return *this; }
|
||||
real_concept& operator=(unsigned long long c) { m_value = static_cast<real_concept_base_type>(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<real_concept_base_type>(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<boost::math::policies::ignore_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<boost::math::policies::ignore_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<boost::math::policies::ignore_error>()));
|
||||
}
|
||||
|
||||
//
|
||||
// Conversion and truncation routines:
|
||||
//
|
||||
template <class Policy>
|
||||
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 <class Policy>
|
||||
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 <class Policy>
|
||||
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 <class Policy>
|
||||
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 <class Policy>
|
||||
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 <class Policy>
|
||||
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 <class charT, class traits>
|
||||
inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const real_concept& a)
|
||||
{
|
||||
return os << a.value();
|
||||
}
|
||||
template <class charT, class traits>
|
||||
inline std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& 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<concepts::real_concept>(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<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
|
||||
{
|
||||
return max_value<concepts::real_concept_base_type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline concepts::real_concept min_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
|
||||
{
|
||||
return min_value<concepts::real_concept_base_type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline concepts::real_concept log_max_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
|
||||
{
|
||||
return log_max_value<concepts::real_concept_base_type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline concepts::real_concept log_min_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
|
||||
{
|
||||
return log_min_value<concepts::real_concept_base_type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline concepts::real_concept epsilon<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
|
||||
{
|
||||
#ifdef __SUNPRO_CC
|
||||
return std::numeric_limits<concepts::real_concept_base_type>::epsilon();
|
||||
#else
|
||||
return tools::epsilon<concepts::real_concept_base_type>();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <>
|
||||
inline constexpr int digits<concepts::real_concept>(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<T>::is_specialized to provide digits.
|
||||
return tools::digits<concepts::real_concept_base_type>();
|
||||
// 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
|
||||
|
||||
|
||||
119
third-party/boost-math/include/boost/math/concepts/real_type_concept.hpp
vendored
Normal file
119
third-party/boost-math/include/boost/math/concepts/real_type_concept.hpp
vendored
Normal file
@ -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 <cmath>
|
||||
#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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
|
||||
|
||||
namespace boost{ namespace math{ namespace concepts{
|
||||
|
||||
template <class RealType>
|
||||
struct RealTypeConcept
|
||||
{
|
||||
template <class Other>
|
||||
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<RealType>();
|
||||
r2 = boost::math::tools::max_value<RealType>();
|
||||
r2 = boost::math::tools::min_value<RealType>();
|
||||
r2 = boost::math::tools::log_max_value<RealType>();
|
||||
r2 = boost::math::tools::log_min_value<RealType>();
|
||||
r2 = boost::math::tools::epsilon<RealType>();
|
||||
}
|
||||
}; // struct DistributionConcept
|
||||
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif
|
||||
|
||||
427
third-party/boost-math/include/boost/math/concepts/std_real_concept.hpp
vendored
Normal file
427
third-party/boost-math/include/boost/math/concepts/std_real_concept.hpp
vendored
Normal file
@ -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 <boost/math/policies/policy.hpp>
|
||||
#include <boost/math/special_functions/math_fwd.hpp>
|
||||
#include <limits>
|
||||
#include <ostream>
|
||||
#include <istream>
|
||||
#include <cmath>
|
||||
|
||||
#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<std_real_concept_base_type>(c)){}
|
||||
std_real_concept(long long c) : m_value(static_cast<std_real_concept_base_type>(c)){}
|
||||
#endif
|
||||
std_real_concept(unsigned long long c) : m_value(static_cast<std_real_concept_base_type>(c)){}
|
||||
std_real_concept(long long c) : m_value(static_cast<std_real_concept_base_type>(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<std_real_concept_base_type>(c); return *this; }
|
||||
std_real_concept& operator=(long long c) { m_value = static_cast<std_real_concept_base_type>(c); return *this; }
|
||||
#endif
|
||||
std_real_concept& operator=(long long c) { m_value = static_cast<std_real_concept_base_type>(c); return *this; }
|
||||
std_real_concept& operator=(unsigned long long c) { m_value = static_cast<std_real_concept_base_type>(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<long double>(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 <boost/math/special_functions/round.hpp>
|
||||
#include <boost/math/special_functions/trunc.hpp>
|
||||
#include <boost/math/special_functions/modf.hpp>
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace concepts{
|
||||
|
||||
//
|
||||
// Conversion and truncation routines:
|
||||
//
|
||||
template <class Policy>
|
||||
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 <class Policy>
|
||||
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 <class Policy>
|
||||
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 <class Policy>
|
||||
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 <class Policy>
|
||||
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 <class Policy>
|
||||
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 <class charT, class traits>
|
||||
inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const std_real_concept& a)
|
||||
{
|
||||
return os << a.value();
|
||||
}
|
||||
template <class charT, class traits>
|
||||
inline std::basic_istream<charT, traits>& operator>>(std::basic_istream<charT, traits>& 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 <boost/math/tools/big_constant.hpp>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
namespace tools
|
||||
{
|
||||
|
||||
template <>
|
||||
inline concepts::std_real_concept make_big_value<concepts::std_real_concept>(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<concepts::std_real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept))
|
||||
{
|
||||
return max_value<concepts::std_real_concept_base_type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline concepts::std_real_concept min_value<concepts::std_real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept))
|
||||
{
|
||||
return min_value<concepts::std_real_concept_base_type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline concepts::std_real_concept log_max_value<concepts::std_real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept))
|
||||
{
|
||||
return log_max_value<concepts::std_real_concept_base_type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline concepts::std_real_concept log_min_value<concepts::std_real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept))
|
||||
{
|
||||
return log_min_value<concepts::std_real_concept_base_type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline concepts::std_real_concept epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept))
|
||||
{
|
||||
return tools::epsilon<concepts::std_real_concept_base_type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline constexpr int digits<concepts::std_real_concept>(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<T>::is_specialized to provide digits.
|
||||
return digits<concepts::std_real_concept_base_type>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline double real_cast<double, concepts::std_real_concept>(concepts::std_real_concept r)
|
||||
{
|
||||
return static_cast<double>(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 <boost/math/special_functions/acosh.hpp>
|
||||
#include <boost/math/special_functions/asinh.hpp>
|
||||
#include <boost/math/special_functions/atanh.hpp>
|
||||
|
||||
#endif // BOOST_MATH_STD_REAL_CONCEPT_HPP
|
||||
1109
third-party/boost-math/include/boost/math/constants/calculate_constants.hpp
vendored
Normal file
1109
third-party/boost-math/include/boost/math/constants/calculate_constants.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
361
third-party/boost-math/include/boost/math/constants/constants.hpp
vendored
Normal file
361
third-party/boost-math/include/boost/math/constants/constants.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
|
||||
#ifndef BOOST_MATH_HAS_NVRTC
|
||||
|
||||
#include <boost/math/tools/cxx03_warn.hpp>
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
#include <boost/math/tools/convert_from_string.hpp>
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4127 4701)
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
#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 <int N>
|
||||
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 <typename Real, typename Policy>
|
||||
struct construction_traits
|
||||
{
|
||||
private:
|
||||
using real_precision = typename policies::precision<Real, Policy>::type;
|
||||
using float_precision = typename policies::precision<float, Policy>::type;
|
||||
using double_precision = typename policies::precision<double, Policy>::type;
|
||||
using long_double_precision = typename policies::precision<long double, Policy>::type;
|
||||
public:
|
||||
using type = std::integral_constant<int,
|
||||
(0 == real_precision::value) ? 0 :
|
||||
std::is_convertible<float, Real>::value && (real_precision::value <= float_precision::value)? construct_from_float :
|
||||
std::is_convertible<double, Real>::value && (real_precision::value <= double_precision::value)? construct_from_double :
|
||||
std::is_convertible<long double, Real>::value && (real_precision::value <= long_double_precision::value)? construct_from_long_double :
|
||||
#ifdef BOOST_MATH_USE_FLOAT128
|
||||
std::is_convertible<BOOST_MATH_FLOAT128_TYPE, Real>::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)<T>);
|
||||
#else
|
||||
#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix)
|
||||
#endif
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <class Real, class Policy = boost::math::policies::policy<> >
|
||||
struct constant_return
|
||||
{
|
||||
using construct_type = typename construction_traits<Real, Policy>::type;
|
||||
using type = typename std::conditional<
|
||||
(construct_type::value == construct_from_string) || (construct_type::value > construct_max),
|
||||
const Real&, Real>::type;
|
||||
};
|
||||
|
||||
template <typename T, const T& (*F)()>
|
||||
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 T, const T& (*F)()>
|
||||
typename constant_initializer<T, F>::initializer const constant_initializer<T, F>::init;
|
||||
|
||||
template <typename T, int N, const T& (*F)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>)) 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 <typename T, int N, const T& (*F)(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>)) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))>
|
||||
typename constant_initializer2<T, N, F>::initializer const constant_initializer2<T, N, F>::init;
|
||||
|
||||
}
|
||||
|
||||
#ifdef BOOST_MATH_USE_FLOAT128
|
||||
# define BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) \
|
||||
static inline constexpr T get(const std::integral_constant<int, construct_from_float128>&) 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<T, & BOOST_MATH_JOIN(constant_, name)<T>::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 <typename T> 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<T>(y));\
|
||||
return result;\
|
||||
}\
|
||||
/* This one is for very high precision that is none the less known at compile time: */ \
|
||||
template <int N> static T compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>)));\
|
||||
template <int N> static inline const T& get_from_compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant<int, N>)))\
|
||||
{\
|
||||
static const T result = compute<N>();\
|
||||
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<T>();\
|
||||
if(digits != current_digits)\
|
||||
{\
|
||||
value = current_digits > max_string_digits ? compute<0>() : T(boost::math::tools::convert_from_string<T>(y));\
|
||||
digits = current_digits; \
|
||||
}\
|
||||
return value;\
|
||||
}\
|
||||
/* public getters come next */\
|
||||
public:\
|
||||
static inline const T& get(const std::integral_constant<int, construct_from_string>&)\
|
||||
{\
|
||||
constant_initializer<T, & BOOST_MATH_JOIN(constant_, name)<T>::get_from_string >::force_instantiate();\
|
||||
return get_from_string();\
|
||||
}\
|
||||
BOOST_MATH_GPU_ENABLED static inline constexpr T get(const std::integral_constant<int, construct_from_float>) noexcept\
|
||||
{ return BOOST_MATH_JOIN(x, F); }\
|
||||
BOOST_MATH_GPU_ENABLED static inline constexpr T get(const std::integral_constant<int, construct_from_double>&) noexcept\
|
||||
{ return x; }\
|
||||
BOOST_MATH_GPU_ENABLED static inline constexpr T get(const std::integral_constant<int, construct_from_long_double>&) noexcept\
|
||||
{ return BOOST_MATH_JOIN(x, L); }\
|
||||
BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) \
|
||||
template <int N> static inline const T& get(const std::integral_constant<int, N>&)\
|
||||
{\
|
||||
constant_initializer2<T, N, & BOOST_MATH_JOIN(constant_, name)<T>::template get_from_compute<N> >::force_instantiate();\
|
||||
return get_from_compute<N>(); \
|
||||
}\
|
||||
/* This one is for true arbitrary precision, which may well vary at runtime: */ \
|
||||
static inline T get(const std::integral_constant<int, 0>&)\
|
||||
{\
|
||||
BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name)\
|
||||
return get_from_variable_precision(); }\
|
||||
}; /* end of struct */\
|
||||
} /* namespace detail */ \
|
||||
\
|
||||
\
|
||||
/* The actual forwarding function: */ \
|
||||
template <typename T, typename Policy> BOOST_MATH_GPU_ENABLED inline constexpr typename detail::constant_return<T, Policy>::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)<T>::get(typename construction_traits<T, Policy>::type()); }\
|
||||
template <typename T> BOOST_MATH_GPU_ENABLED inline constexpr typename detail::constant_return<T>::type name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_MATH_NOEXCEPT(T)\
|
||||
{ return name<T, boost::math::policies::policy<> >(); }\
|
||||
\
|
||||
\
|
||||
/* 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 <typename T> BOOST_MATH_GPU_ENABLED constexpr T name() noexcept { return static_cast<T>(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 <typename T>
|
||||
BOOST_MATH_GPU_ENABLED inline constexpr T tau() { return two_pi<T>(); }
|
||||
|
||||
} // 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 <boost/math/constants/calculate_constants.hpp>
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MATH_CONSTANTS_CONSTANTS_INCLUDED
|
||||
|
||||
|
||||
169
third-party/boost-math/include/boost/math/constants/info.hpp
vendored
Normal file
169
third-party/boost-math/include/boost/math/constants/info.hpp
vendored
Normal file
@ -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 <boost/math/constants/constants.hpp>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#ifndef BOOST_MATH_NO_RTTI
|
||||
#include <typeinfo>
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math{ namespace constants{
|
||||
|
||||
namespace detail{
|
||||
|
||||
template <class T>
|
||||
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<float>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(float))
|
||||
{
|
||||
return "float";
|
||||
}
|
||||
template <>
|
||||
const char* nameof<double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(double))
|
||||
{
|
||||
return "double";
|
||||
}
|
||||
template <>
|
||||
const char* nameof<long double>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(long double))
|
||||
{
|
||||
return "long double";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
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<T>() <<
|
||||
"\n\n"
|
||||
"Checking for std::numeric_limits<" << nameof<T>() << "> specialisation: " <<
|
||||
(std::numeric_limits<T>::is_specialized ? "yes" : "no") << std::endl;
|
||||
if(std::numeric_limits<T>::is_specialized)
|
||||
{
|
||||
os <<
|
||||
"std::numeric_limits<" << nameof<T>() << ">::digits reports that the radix is " << std::numeric_limits<T>::radix << ".\n";
|
||||
if (std::numeric_limits<T>::radix == 2)
|
||||
{
|
||||
os <<
|
||||
"std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n" << std::numeric_limits<T>::digits << " binary digits.\n";
|
||||
}
|
||||
else if (std::numeric_limits<T>::radix == 10)
|
||||
{
|
||||
os <<
|
||||
"std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n" << std::numeric_limits<T>::digits10 << " decimal digits.\n";
|
||||
os <<
|
||||
"std::numeric_limits<" << nameof<T>() << ">::digits reports that the precision is \n"
|
||||
<< std::numeric_limits<T>::digits * 1000L /301L << " binary digits.\n"; // divide by log2(10) - about 3 bits per decimal digit.
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "Unknown radix = " << std::numeric_limits<T>::radix << "\n";
|
||||
}
|
||||
}
|
||||
typedef typename boost::math::policies::precision<T, Policy>::type precision_type;
|
||||
if(precision_type::value)
|
||||
{
|
||||
if (std::numeric_limits<T>::radix == 2)
|
||||
{
|
||||
os <<
|
||||
"boost::math::policies::precision<" << nameof<T>() << ", " << nameof<Policy>() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n";
|
||||
}
|
||||
else if (std::numeric_limits<T>::radix == 10)
|
||||
{
|
||||
os <<
|
||||
"boost::math::policies::precision<" << nameof<T>() << ", " << nameof<Policy>() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "Unknown radix = " << std::numeric_limits<T>::radix << "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
os <<
|
||||
"boost::math::policies::precision<" << nameof<T>() << ", Policy> \n"
|
||||
"reports that there is no compile type precision available.\n"
|
||||
"boost::math::tools::digits<" << nameof<T>() << ">() \n"
|
||||
"reports that the current runtime precision is \n" <<
|
||||
boost::math::tools::digits<T>() << " binary digits.\n";
|
||||
}
|
||||
|
||||
typedef typename construction_traits<T, Policy>::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<T>() > 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 <class T>
|
||||
void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
|
||||
{
|
||||
print_info_on_type<T, boost::math::policies::policy<> >(os);
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif // BOOST_MATH_CONSTANTS_INFO_INCLUDED
|
||||
1012
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_cmath.hpp
vendored
Normal file
1012
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_cmath.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
38
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex.hpp
vendored
Normal file
38
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex.hpp
vendored
Normal file
@ -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 <complex>.
|
||||
|
||||
#ifndef BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_
|
||||
#define BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_
|
||||
|
||||
#include <boost/math/cstdfloat/cstdfloat_types.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_limits.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_cmath.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_iostream.hpp>
|
||||
|
||||
#if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS)
|
||||
#error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS defined.
|
||||
#endif
|
||||
#if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH)
|
||||
#error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined.
|
||||
#endif
|
||||
#if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM)
|
||||
#error You can not use <boost/math/cstdfloat/cstdfloat_complex.hpp> 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 <boost/math/cstdfloat/cstdfloat_complex_std.hpp>
|
||||
#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_
|
||||
813
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp
vendored
Normal file
813
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_complex_std.hpp
vendored
Normal file
@ -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 <complex>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/tools/cxx03_warn.hpp>
|
||||
|
||||
namespace std
|
||||
{
|
||||
// Forward declarations.
|
||||
template<class float_type>
|
||||
class complex;
|
||||
|
||||
template<>
|
||||
class complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>;
|
||||
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> conj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> proj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&,
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& = 0);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sin (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cos (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tan (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asin (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acos (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atan (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> exp (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log10(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&,
|
||||
int);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&,
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&,
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow (const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&,
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sinh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cosh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tanh (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
template<class char_type, class traits_type>
|
||||
inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>&, const std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
template<class char_type, class traits_type>
|
||||
inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>&, std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>&);
|
||||
|
||||
// Template specialization of the complex class.
|
||||
template<>
|
||||
class complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>
|
||||
{
|
||||
public:
|
||||
typedef BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE value_type;
|
||||
|
||||
complex(const complex<float>&);
|
||||
complex(const complex<double>&);
|
||||
complex(const complex<long double>&);
|
||||
|
||||
#if defined(BOOST_NO_CXX11_CONSTEXPR)
|
||||
complex(const value_type& r = value_type(),
|
||||
const value_type& i = value_type()) : re(r),
|
||||
im(i) { }
|
||||
|
||||
template<typename X>
|
||||
explicit complex(const complex<X>& 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<typename X>
|
||||
explicit constexpr complex(const complex<X>& 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<value_type>& operator=(const value_type& v)
|
||||
{
|
||||
re = v;
|
||||
im = value_type(0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
complex<value_type>& operator+=(const value_type& v)
|
||||
{
|
||||
re += v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
complex<value_type>& operator-=(const value_type& v)
|
||||
{
|
||||
re -= v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
complex<value_type>& operator*=(const value_type& v)
|
||||
{
|
||||
re *= v;
|
||||
im *= v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
complex<value_type>& operator/=(const value_type& v)
|
||||
{
|
||||
re /= v;
|
||||
im /= v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
complex<value_type>& operator=(const complex<X>& x)
|
||||
{
|
||||
re = x.real();
|
||||
im = x.imag();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
complex<value_type>& operator+=(const complex<X>& x)
|
||||
{
|
||||
re += x.real();
|
||||
im += x.imag();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
complex<value_type>& operator-=(const complex<X>& x)
|
||||
{
|
||||
re -= x.real();
|
||||
im -= x.imag();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
complex<value_type>& operator*=(const complex<X>& 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<typename X>
|
||||
complex<value_type>& operator/=(const complex<X>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<float>& f) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.imag())) { }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<double>& d) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.imag())) { }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::complex(const complex<long double>& 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<class float_type> inline std::complex<float_type> multiply_by_i(const std::complex<float_type>& x)
|
||||
{
|
||||
// Multiply x (in C) by I (the imaginary component), and return the result.
|
||||
return std::complex<float_type>(-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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return x.real(); }
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return x.imag(); }
|
||||
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::sqrt; return sqrt ((real(x) * real(x)) + (imag(x) * imag(x))); }
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { using std::atan2; return atan2(x.imag(), x.real()); }
|
||||
inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return (real(x) * real(x)) + (imag(x) * imag(x)); }
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> conj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(x.real(), -x.imag()); }
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> proj (const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE m = (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(), x.imag() < 0 ? -0 : 0);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(rho * cos(theta), rho * sin(theta));
|
||||
}
|
||||
|
||||
// Global add, sub, mul, div.
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() + v.real(), u.imag() + v.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() - v.real(), u.imag() - v.imag()); }
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v)
|
||||
{
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>((u.real() * v.real()) - (u.imag() * v.imag()),
|
||||
(u.real() * v.imag()) + (u.imag() * v.real()));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v)
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE the_norm = std::norm(v);
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(((u.real() * v.real()) + (u.imag() * v.imag())) / the_norm,
|
||||
((u.imag() * v.real()) - (u.real() * v.imag())) / the_norm);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() + v, u.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() - v, u.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() * v, u.imag() * v); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u.real() / v, u.imag() / v); }
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u + v.real(), v.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u - v.real(), -v.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator*(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(u * v.real(), u * v.imag()); }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator/(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& v) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE v_norm = norm(v); return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>((u * v.real()) / v_norm, (-u * v.imag()) / v_norm); }
|
||||
|
||||
// Unary plus / minus.
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator+(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u) { return u; }
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> operator-(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& u) { return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(-u.real(), -u.imag()); }
|
||||
|
||||
// Equality and inequality.
|
||||
inline bool operator==(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x.real() == y.real()) && (x.imag() == y.imag())); }
|
||||
inline bool operator==(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x == y.real()) && (y.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); }
|
||||
inline bool operator!=(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x, const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& y) { return ((x.real() != y.real()) || (x.imag() != y.imag())); }
|
||||
inline bool operator!=(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sqrt(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sqrt_xi_half, sqrt_xi_half);
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sin(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sin_x * cosh_y, cos_x * sinh_y);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cos(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_x * cosh_y, -(sin_x * sinh_y));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tan(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(sin_x * cosh_y, cos_x * sinh_y)
|
||||
/ complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_x * cosh_y, -sin_x * sinh_y));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asin(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acos(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
return boost::math::constants::half_pi<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>() - std::asin(x);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atan(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> exp(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
using std::exp;
|
||||
|
||||
return std::polar(exp(x.real()), x.imag());
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
: bool(-x.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
: bool(-x.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()));
|
||||
|
||||
if(re_isnan || im_isnan) { return x; }
|
||||
|
||||
if(re_isinf || im_isinf)
|
||||
{
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>
|
||||
(
|
||||
-std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(),
|
||||
BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0.0)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(im_isneg == false)
|
||||
{
|
||||
return std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>
|
||||
(
|
||||
log(x.imag()),
|
||||
boost::math::constants::half_pi<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>
|
||||
(
|
||||
log(-x.imag()),
|
||||
-boost::math::constants::half_pi<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(log(std::norm(x)) / 2, atan2(x.imag(), x.real()));
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> log10(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
return std::log(x) / boost::math::constants::ln_ten<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>();
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
: bool(-x.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
: bool(-x.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)()));
|
||||
|
||||
if(re_isnan || im_isnan) { return x; }
|
||||
|
||||
if(re_isinf || im_isinf)
|
||||
{
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN(),
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN());
|
||||
}
|
||||
|
||||
if(p < 0)
|
||||
{
|
||||
if(std::abs(x) < (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::min)())
|
||||
{
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(),
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::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>(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(p == 1) { return x; }
|
||||
|
||||
if(std::abs(x) > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE re = (re_isneg ? -std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()
|
||||
: +std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity());
|
||||
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE im = (im_isneg ? -std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()
|
||||
: +std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity());
|
||||
|
||||
return complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(re, im);
|
||||
}
|
||||
|
||||
if (p == 2) { return (x * x); }
|
||||
else if(p == 3) { return ((x * x) * x); }
|
||||
else if(p == 4) { const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> x2 = (x * x); return (x2 * x2); }
|
||||
else
|
||||
{
|
||||
// The variable xn stores the binary powers of x.
|
||||
complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> result(((p % 2) != 0) ? x : complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1)));
|
||||
complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(pxa, BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::exp(a * std::log(x));
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x,
|
||||
const complex<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;
|
||||
|
||||
return pow(x.real(), a);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::exp(a * std::log(x));
|
||||
}
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x,
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& a)
|
||||
{
|
||||
const bool x_isneg = (x < 0);
|
||||
const bool x_isnan = (x != x);
|
||||
const bool x_isinf = ((!x_isneg) ? bool(+x > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
: bool(-x > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
: bool(-a.real() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::max)())
|
||||
: bool(-a.imag() > (std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> result;
|
||||
|
||||
if(args_is_nan)
|
||||
{
|
||||
result =
|
||||
complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>
|
||||
(
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN(),
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN()
|
||||
);
|
||||
}
|
||||
else if(x_isinf)
|
||||
{
|
||||
if(a_is_finite)
|
||||
{
|
||||
result =
|
||||
complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>
|
||||
(
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity(),
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::infinity()
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
result =
|
||||
complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>
|
||||
(
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN(),
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>
|
||||
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>
|
||||
(
|
||||
BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0),
|
||||
BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
result =
|
||||
complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>
|
||||
(
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN(),
|
||||
std::numeric_limits<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>::quiet_NaN()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> sinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_y * sinh_x, cosh_x * sin_y);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> cosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(cos_y * cosh_x, sin_y * sinh_x);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> tanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> ex_plus = std::exp(x);
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> ex_minus = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / ex_plus;
|
||||
|
||||
return (ex_plus - ex_minus) / (ex_plus + ex_minus);
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> asinh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
return std::log(x + std::sqrt((x * x) + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1)));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> acosh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE my_one(1);
|
||||
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> zp(x.real() + my_one, x.imag());
|
||||
const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> zm(x.real() - my_one, x.imag());
|
||||
|
||||
return std::log(x + (zp * std::sqrt(zm / zp)));
|
||||
}
|
||||
|
||||
inline complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE> atanh(const complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& 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<class char_type, class traits_type>
|
||||
inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>& os, const std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
std::basic_ostringstream<char_type, traits_type> 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<class char_type, class traits_type>
|
||||
inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>& is, std::complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>& x)
|
||||
{
|
||||
BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE rx;
|
||||
BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE ix;
|
||||
|
||||
char_type the_char;
|
||||
|
||||
static_cast<void>(is >> the_char);
|
||||
|
||||
if(the_char == static_cast<char_type>('('))
|
||||
{
|
||||
static_cast<void>(is >> rx >> the_char);
|
||||
|
||||
if(the_char == static_cast<char_type>(','))
|
||||
{
|
||||
static_cast<void>(is >> ix >> the_char);
|
||||
|
||||
if(the_char == static_cast<char_type>(')'))
|
||||
{
|
||||
x = complex<BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE>(rx, ix);
|
||||
}
|
||||
else
|
||||
{
|
||||
is.setstate(ios_base::failbit);
|
||||
}
|
||||
}
|
||||
else if(the_char == static_cast<char_type>(')'))
|
||||
{
|
||||
x = rx;
|
||||
}
|
||||
else
|
||||
{
|
||||
is.setstate(ios_base::failbit);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
static_cast<void>(is.putback(the_char));
|
||||
|
||||
static_cast<void>(is >> rx);
|
||||
|
||||
x = rx;
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
#endif // BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_
|
||||
822
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_iostream.hpp
vendored
Normal file
822
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_iostream.hpp
vendored
Normal file
@ -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 <boost/math/cstdfloat/cstdfloat_types.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_limits.hpp>
|
||||
#include <boost/math/cstdfloat/cstdfloat_cmath.hpp>
|
||||
|
||||
#if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH)
|
||||
#error You can not use <boost/math/cstdfloat/cstdfloat_iostream.hpp> 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 <cstddef>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
#include <boost/math/tools/nothrow.hpp>
|
||||
#include <boost/math/tools/throw_exception.hpp>
|
||||
|
||||
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<char>(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<typename char_type, class traits_type>
|
||||
inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>& os, const boost::math::cstdfloat::detail::float_internal128_t& x)
|
||||
{
|
||||
std::basic_ostringstream<char_type, traits_type> ostr;
|
||||
ostr.flags(os.flags());
|
||||
ostr.imbue(os.getloc());
|
||||
ostr.precision(os.precision());
|
||||
|
||||
char my_buffer[64U];
|
||||
|
||||
const int my_prec = static_cast<int>(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<int>(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<int>(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<void>(ostr << my_buffer2);
|
||||
|
||||
delete [] my_buffer2;
|
||||
}
|
||||
else
|
||||
{
|
||||
static_cast<void>(ostr << my_buffer);
|
||||
}
|
||||
|
||||
return (os << ostr.str());
|
||||
}
|
||||
|
||||
template<typename char_type, class traits_type>
|
||||
inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>& 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<std::ptrdiff_t>(p_end - str.c_str()) != static_cast<std::ptrdiff_t>(str.length()))
|
||||
{
|
||||
for(std::string::const_reverse_iterator it = str.rbegin(); it != str.rend(); ++it)
|
||||
{
|
||||
static_cast<void>(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 <cstring>
|
||||
#include <cctype>
|
||||
|
||||
namespace boost { namespace math { namespace cstdfloat { namespace detail {
|
||||
|
||||
template<class string_type>
|
||||
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<int>((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<std::ptrdiff_t>(str.size());
|
||||
chars = digits - chars;
|
||||
|
||||
if(scientific)
|
||||
{
|
||||
++chars;
|
||||
}
|
||||
|
||||
if(chars > 0)
|
||||
{
|
||||
str.append(static_cast<size_type>(chars), '0');
|
||||
}
|
||||
}
|
||||
|
||||
if(fixed || (!scientific && (my_exp >= -4) && (my_exp < digits)))
|
||||
{
|
||||
if((1 + my_exp) > static_cast<int>(str.size()))
|
||||
{
|
||||
// Just pad out the end with zeros.
|
||||
str.append(static_cast<size_type>((1 + my_exp) - static_cast<int>(str.size())), '0');
|
||||
|
||||
if(showpoint || fixed)
|
||||
{
|
||||
str.append(".");
|
||||
}
|
||||
}
|
||||
else if(my_exp + 1 < static_cast<int>(str.size()))
|
||||
{
|
||||
if(my_exp < 0)
|
||||
{
|
||||
str.insert(0U, static_cast<size_type>(-1 - my_exp), '0');
|
||||
str.insert(0U, "0.");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert the decimal point:
|
||||
str.insert(static_cast<size_type>(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<int>(str.find('.') + 1U);
|
||||
l = digits - (static_cast<int>(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<class float_type, class type_a> inline void eval_convert_to(type_a* pa, const float_type& cb) { *pa = static_cast<type_a>(cb); }
|
||||
template<class float_type, class type_a> inline void eval_add (float_type& b, const type_a& a) { b += a; }
|
||||
template<class float_type, class type_a> inline void eval_subtract (float_type& b, const type_a& a) { b -= a; }
|
||||
template<class float_type, class type_a> inline void eval_multiply (float_type& b, const type_a& a) { b *= a; }
|
||||
template<class float_type> inline void eval_multiply (float_type& b, const float_type& cb, const float_type& cb2) { b = (cb * cb2); }
|
||||
template<class float_type, class type_a> inline void eval_divide (float_type& b, const type_a& a) { b /= a; }
|
||||
template<class float_type> inline void eval_log10 (float_type& b, const float_type& cb) { b = std::log10(cb); }
|
||||
template<class float_type> 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<class float_type>
|
||||
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<float_type>::min)())
|
||||
: bool(-x < (std::numeric_limits<float_type>::min)()));
|
||||
const bool isnan = (x != x);
|
||||
const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits<float_type>::max)())
|
||||
: bool(-x > (std::numeric_limits<float_type>::max)()));
|
||||
|
||||
int expon = 0;
|
||||
|
||||
if(digits <= 0) { digits = std::numeric_limits<float_type>::max_digits10; }
|
||||
|
||||
const int org_digits = static_cast<int>(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<float_type>::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<char>('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<int>(*result.rbegin() - '0') & 1) != 0)
|
||||
{
|
||||
round_string_up_at(result, static_cast<int>(result.size() - 1U), expon);
|
||||
if (digits == 0) digits = 1;
|
||||
}
|
||||
}
|
||||
else if(cdigit >= 5)
|
||||
{
|
||||
round_string_up_at(result, static_cast<int>(result.size() - 1u), expon);
|
||||
if (digits == 0) digits = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while((result.size() > static_cast<std::string::size_type>(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 <class float_type>
|
||||
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<float_type>::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<int>(*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<int>(*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<float_type>::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<typename char_type, class traits_type>
|
||||
inline std::basic_ostream<char_type, traits_type>& operator<<(std::basic_ostream<char_type, traits_type>& 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<char_type, traits_type> ostr;
|
||||
ostr.flags(os.flags());
|
||||
ostr.imbue(os.getloc());
|
||||
ostr.precision(os.precision());
|
||||
|
||||
static_cast<void>(ostr << str);
|
||||
|
||||
return (os << ostr.str());
|
||||
}
|
||||
|
||||
template<typename char_type, class traits_type>
|
||||
inline std::basic_istream<char_type, traits_type>& operator>>(std::basic_istream<char_type, traits_type>& 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<void>(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_
|
||||
87
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_limits.hpp
vendored
Normal file
87
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_limits.hpp
vendored
Normal file
@ -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 <boost/math/cstdfloat/cstdfloat_types.hpp>
|
||||
|
||||
#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 <limits>
|
||||
#include <boost/math/tools/nothrow.hpp>
|
||||
|
||||
// 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<boost::math::cstdfloat::detail::float_internal128_t>
|
||||
{
|
||||
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<int>((min_exponent * 301L) / 1000L);
|
||||
static constexpr int max_exponent = +16384;
|
||||
static constexpr int max_exponent10 = static_cast<int>((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_
|
||||
|
||||
441
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_types.hpp
vendored
Normal file
441
third-party/boost-math/include/boost/math/cstdfloat/cstdfloat_types.hpp
vendored
Normal file
@ -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 <cfloat>
|
||||
#include <limits>
|
||||
#include <boost/math/tools/config.hpp>
|
||||
|
||||
// This is the beginning of the preamble.
|
||||
|
||||
// In this preamble, the preprocessor is used to query certain
|
||||
// preprocessor definitions from <cfloat>. 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 <boost/cstdfloat.hpp>.
|
||||
#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
|
||||
// <boost/math/tools/config.hpp>.
|
||||
|
||||
#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 <boost/cstdfloat.hpp>."
|
||||
#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 <boost/cstdfloat.hpp>.
|
||||
#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 <boost/cstdfloat.hpp> 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<boost::float16_t>::is_iec559 == true, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float16_t>::radix == 2, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float16_t>::digits == 11, "boost::float16_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float16_t>::max_exponent == 16, "boost::float16_t has been detected in <boost/cstdfloat>, 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<boost::float32_t>::is_iec559 == true, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float32_t>::radix == 2, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float32_t>::digits == 24, "boost::float32_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float32_t>::max_exponent == 128, "boost::float32_t has been detected in <boost/cstdfloat>, 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<boost::float64_t>::is_iec559 == true, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float64_t>::radix == 2, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float64_t>::digits == 53, "boost::float64_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float64_t>::max_exponent == 1024, "boost::float64_t has been detected in <boost/cstdfloat>, 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<boost::float80_t>::is_iec559 == true, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float80_t>::radix == 2, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float80_t>::digits == 64, "boost::float80_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float80_t>::max_exponent == 16384, "boost::float80_t has been detected in <boost/cstdfloat>, 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<boost::float128_t>.
|
||||
// Support for std::numeric_limits<boost::float128_t> is added in the detail
|
||||
// file <boost/math/cstdfloat/cstdfloat_limits.hpp>.
|
||||
#else
|
||||
static_assert(std::numeric_limits<boost::float128_t>::is_iec559 == true, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float128_t>::radix == 2, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float128_t>::digits == 113, "boost::float128_t has been detected in <boost/cstdfloat>, but verification with std::numeric_limits fails");
|
||||
static_assert(std::numeric_limits<boost::float128_t>::max_exponent == 16384, "boost::float128_t has been detected in <boost/cstdfloat>, 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 <boost/cstdfloat.hpp> 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_
|
||||
|
||||
2061
third-party/boost-math/include/boost/math/differentiation/autodiff.hpp
vendored
Normal file
2061
third-party/boost-math/include/boost/math/differentiation/autodiff.hpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
387
third-party/boost-math/include/boost/math/differentiation/autodiff_cpp11.hpp
vendored
Normal file
387
third-party/boost-math/include/boost/math/differentiation/autodiff_cpp11.hpp
vendored
Normal file
@ -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 <type_traits>
|
||||
#include <boost/math/tools/mp.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace math {
|
||||
|
||||
namespace mp = tools::meta_programming;
|
||||
|
||||
namespace differentiation {
|
||||
inline namespace autodiff_v1 {
|
||||
namespace detail {
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
fvar<RealType, Order>::fvar(root_type const& ca, bool const is_variable) {
|
||||
fvar_cpp11(is_fvar<RealType>{}, ca, is_variable);
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename RootType>
|
||||
void fvar<RealType, Order>::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<RealType>(0));
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename RootType>
|
||||
void fvar<RealType, Order>::fvar_cpp11(std::false_type, RootType const& ca, bool const is_variable) {
|
||||
v.front() = ca;
|
||||
if (0 < Order) {
|
||||
v[1] = static_cast<root_type>(static_cast<int>(is_variable));
|
||||
if (1 < Order)
|
||||
std::fill(v.begin() + 2, v.end(), static_cast<RealType>(0));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename... Orders>
|
||||
get_type_at<RealType, sizeof...(Orders)> fvar<RealType, Order>::at_cpp11(std::true_type,
|
||||
size_t order,
|
||||
Orders...) const {
|
||||
return v.at(order);
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename... Orders>
|
||||
get_type_at<RealType, sizeof...(Orders)> fvar<RealType, Order>::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 <typename RealType, size_t Order>
|
||||
template <typename... Orders>
|
||||
get_type_at<RealType, sizeof...(Orders)> fvar<RealType, Order>::at(size_t order, Orders... orders) const {
|
||||
return at_cpp11(std::integral_constant<bool, sizeof...(orders) == 0>{}, order, orders...);
|
||||
}
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
constexpr T product(Ts...) {
|
||||
return static_cast<T>(1);
|
||||
}
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
constexpr T product(T factor, Ts... factors) {
|
||||
return factor * product<T>(factors...);
|
||||
}
|
||||
|
||||
// Can throw "std::out_of_range: array::at: __n (which is 7) >= _Nm (which is 7)"
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename... Orders>
|
||||
get_type_at<fvar<RealType, Order>, sizeof...(Orders)> fvar<RealType, Order>::derivative(
|
||||
Orders... orders) const {
|
||||
static_assert(sizeof...(Orders) <= depth,
|
||||
"Number of parameters to derivative(...) cannot exceed fvar::depth.");
|
||||
return at(static_cast<size_t>(orders)...) *
|
||||
product(boost::math::factorial<root_type>(static_cast<unsigned>(orders))...);
|
||||
}
|
||||
|
||||
template <typename RootType, typename Func>
|
||||
class Curry {
|
||||
Func const& f_;
|
||||
size_t const i_;
|
||||
|
||||
public:
|
||||
template <typename SizeType> // typename SizeType to force inline constructor.
|
||||
Curry(Func const& f, SizeType i) : f_(f), i_(static_cast<std::size_t>(i)) {}
|
||||
template <typename... Indices>
|
||||
RootType operator()(Indices... indices) const {
|
||||
using unsigned_t = typename std::make_unsigned<typename std::common_type<Indices>::type...>::type;
|
||||
return f_(i_, static_cast<unsigned_t>(indices)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename Func, typename Fvar, typename... Fvars>
|
||||
promote<fvar<RealType, Order>, Fvar, Fvars...> fvar<RealType, Order>::apply_coefficients(
|
||||
size_t const order,
|
||||
Func const& f,
|
||||
Fvar const& cr,
|
||||
Fvars&&... fvars) const {
|
||||
fvar<RealType, Order> const epsilon = fvar<RealType, Order>(*this).set_root(0);
|
||||
size_t i = order < order_sum ? order : order_sum;
|
||||
using return_type = promote<fvar<RealType, Order>, Fvar, Fvars...>;
|
||||
return_type accumulator = cr.apply_coefficients(
|
||||
order - i, Curry<typename return_type::root_type, Func>(f, i), std::forward<Fvars>(fvars)...);
|
||||
while (i--)
|
||||
(accumulator *= epsilon) += cr.apply_coefficients(
|
||||
order - i, Curry<typename return_type::root_type, Func>(f, i), std::forward<Fvars>(fvars)...);
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename Func, typename Fvar, typename... Fvars>
|
||||
promote<fvar<RealType, Order>, Fvar, Fvars...> fvar<RealType, Order>::apply_coefficients_nonhorner(
|
||||
size_t const order,
|
||||
Func const& f,
|
||||
Fvar const& cr,
|
||||
Fvars&&... fvars) const {
|
||||
fvar<RealType, Order> const epsilon = fvar<RealType, Order>(*this).set_root(0);
|
||||
fvar<RealType, Order> epsilon_i = fvar<RealType, Order>(1); // epsilon to the power of i
|
||||
using return_type = promote<fvar<RealType, Order>, Fvar, Fvars...>;
|
||||
return_type accumulator = cr.apply_coefficients_nonhorner(
|
||||
order, Curry<typename return_type::root_type, Func>(f, 0), std::forward<Fvars>(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<typename return_type::root_type, Func>(f, i), std::forward<Fvars>(fvars)...),
|
||||
0,
|
||||
0);
|
||||
}
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename Func, typename Fvar, typename... Fvars>
|
||||
promote<fvar<RealType, Order>, Fvar, Fvars...> fvar<RealType, Order>::apply_derivatives(
|
||||
size_t const order,
|
||||
Func const& f,
|
||||
Fvar const& cr,
|
||||
Fvars&&... fvars) const {
|
||||
fvar<RealType, Order> const epsilon = fvar<RealType, Order>(*this).set_root(0);
|
||||
size_t i = order < order_sum ? order : order_sum;
|
||||
using return_type = promote<fvar<RealType, Order>, Fvar, Fvars...>;
|
||||
return_type accumulator =
|
||||
cr.apply_derivatives(
|
||||
order - i, Curry<typename return_type::root_type, Func>(f, i), std::forward<Fvars>(fvars)...) /
|
||||
factorial<root_type>(static_cast<unsigned>(i));
|
||||
while (i--)
|
||||
(accumulator *= epsilon) +=
|
||||
cr.apply_derivatives(
|
||||
order - i, Curry<typename return_type::root_type, Func>(f, i), std::forward<Fvars>(fvars)...) /
|
||||
factorial<root_type>(static_cast<unsigned>(i));
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename Func, typename Fvar, typename... Fvars>
|
||||
promote<fvar<RealType, Order>, Fvar, Fvars...> fvar<RealType, Order>::apply_derivatives_nonhorner(
|
||||
size_t const order,
|
||||
Func const& f,
|
||||
Fvar const& cr,
|
||||
Fvars&&... fvars) const {
|
||||
fvar<RealType, Order> const epsilon = fvar<RealType, Order>(*this).set_root(0);
|
||||
fvar<RealType, Order> epsilon_i = fvar<RealType, Order>(1); // epsilon to the power of i
|
||||
using return_type = promote<fvar<RealType, Order>, Fvar, Fvars...>;
|
||||
return_type accumulator = cr.apply_derivatives_nonhorner(
|
||||
order, Curry<typename return_type::root_type, Func>(f, 0), std::forward<Fvars>(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<typename return_type::root_type, Func>(f, i), std::forward<Fvars>(fvars)...) /
|
||||
factorial<root_type>(static_cast<unsigned>(i)),
|
||||
0,
|
||||
0);
|
||||
}
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename SizeType>
|
||||
fvar<RealType, Order> fvar<RealType, Order>::epsilon_multiply_cpp11(std::true_type,
|
||||
SizeType z0,
|
||||
size_t isum0,
|
||||
fvar<RealType, Order> 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<RealType, Order> retval = fvar<RealType, Order>();
|
||||
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 <typename RealType, size_t Order>
|
||||
template <typename SizeType>
|
||||
fvar<RealType, Order> fvar<RealType, Order>::epsilon_multiply_cpp11(std::false_type,
|
||||
SizeType z0,
|
||||
size_t isum0,
|
||||
fvar<RealType, Order> const& cr,
|
||||
size_t z1,
|
||||
size_t isum1) const {
|
||||
using ssize_t = typename std::make_signed<std::size_t>::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<RealType, Order> retval = fvar<RealType, Order>();
|
||||
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 <typename RealType, size_t Order>
|
||||
fvar<RealType, Order> fvar<RealType, Order>::epsilon_multiply(size_t z0,
|
||||
size_t isum0,
|
||||
fvar<RealType, Order> const& cr,
|
||||
size_t z1,
|
||||
size_t isum1) const {
|
||||
return epsilon_multiply_cpp11(is_fvar<RealType>{}, z0, isum0, cr, z1, isum1);
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename SizeType>
|
||||
fvar<RealType, Order> fvar<RealType, Order>::epsilon_multiply_cpp11(std::true_type,
|
||||
SizeType z0,
|
||||
size_t isum0,
|
||||
root_type const& ca) const {
|
||||
fvar<RealType, Order> 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 <typename RealType, size_t Order>
|
||||
template <typename SizeType>
|
||||
fvar<RealType, Order> fvar<RealType, Order>::epsilon_multiply_cpp11(std::false_type,
|
||||
SizeType z0,
|
||||
size_t isum0,
|
||||
root_type const& ca) const {
|
||||
fvar<RealType, Order> 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<RealType>(0))
|
||||
retval.v[i] *= ca;
|
||||
return retval;
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
fvar<RealType, Order> fvar<RealType, Order>::epsilon_multiply(size_t z0,
|
||||
size_t isum0,
|
||||
root_type const& ca) const {
|
||||
return epsilon_multiply_cpp11(is_fvar<RealType>{}, z0, isum0, ca);
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename RootType>
|
||||
fvar<RealType, Order>& fvar<RealType, Order>::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 <typename RealType, size_t Order>
|
||||
template <typename RootType>
|
||||
fvar<RealType, Order>& fvar<RealType, Order>::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 <typename RealType, size_t Order>
|
||||
fvar<RealType, Order>& fvar<RealType, Order>::multiply_assign_by_root_type(bool is_root,
|
||||
root_type const& ca) {
|
||||
return multiply_assign_by_root_type_cpp11(is_fvar<RealType>{}, is_root, ca);
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename RootType>
|
||||
fvar<RealType, Order>& fvar<RealType, Order>::negate_cpp11(std::true_type, RootType const&) {
|
||||
std::for_each(v.begin(), v.end(), [](RealType& r) { r.negate(); });
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename RootType>
|
||||
fvar<RealType, Order>& fvar<RealType, Order>::negate_cpp11(std::false_type, RootType const&) {
|
||||
std::for_each(v.begin(), v.end(), [](RealType& a) { a = -a; });
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
fvar<RealType, Order>& fvar<RealType, Order>::negate() {
|
||||
return negate_cpp11(is_fvar<RealType>{}, static_cast<root_type>(*this));
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename RootType>
|
||||
fvar<RealType, Order>& fvar<RealType, Order>::set_root_cpp11(std::true_type, RootType const& root) {
|
||||
v.front().set_root(root);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
template <typename RootType>
|
||||
fvar<RealType, Order>& fvar<RealType, Order>::set_root_cpp11(std::false_type, RootType const& root) {
|
||||
v.front() = root;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order>
|
||||
fvar<RealType, Order>& fvar<RealType, Order>::set_root(root_type const& root) {
|
||||
return set_root_cpp11(is_fvar<RealType>{}, root);
|
||||
}
|
||||
|
||||
template <typename RealType, size_t Order, size_t... Is>
|
||||
auto make_fvar_for_tuple(mp::index_sequence<Is...>, RealType const& ca)
|
||||
-> decltype(make_fvar<RealType, zero<Is>::value..., Order>(ca)) {
|
||||
return make_fvar<RealType, zero<Is>::value..., Order>(ca);
|
||||
}
|
||||
|
||||
template <typename RealType, size_t... Orders, size_t... Is, typename... RealTypes>
|
||||
auto make_ftuple_impl(mp::index_sequence<Is...>, RealTypes const&... ca)
|
||||
-> decltype(std::make_tuple(make_fvar_for_tuple<RealType, Orders>(mp::make_index_sequence<Is>{},
|
||||
ca)...)) {
|
||||
return std::make_tuple(make_fvar_for_tuple<RealType, Orders>(mp::make_index_sequence<Is>{}, ca)...);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename RealType, size_t... Orders, typename... RealTypes>
|
||||
auto make_ftuple(RealTypes const&... ca)
|
||||
-> decltype(detail::make_ftuple_impl<RealType, Orders...>(mp::index_sequence_for<RealTypes...>{},
|
||||
ca...)) {
|
||||
static_assert(sizeof...(Orders) == sizeof...(RealTypes),
|
||||
"Number of Orders must match number of function parameters.");
|
||||
return detail::make_ftuple_impl<RealType, Orders...>(mp::index_sequence_for<RealTypes...>{}, ca...);
|
||||
}
|
||||
|
||||
} // namespace autodiff_v1
|
||||
} // namespace differentiation
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
266
third-party/boost-math/include/boost/math/differentiation/finite_difference.hpp
vendored
Normal file
266
third-party/boost-math/include/boost/math/differentiation/finite_difference.hpp
vendored
Normal file
@ -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 <complex>
|
||||
#include <boost/math/special_functions/next.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace differentiation {
|
||||
|
||||
namespace detail {
|
||||
template<class Real>
|
||||
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<Real>::max)()) - x;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
template<class F, class Real>
|
||||
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<Real>::epsilon)();
|
||||
constexpr const Real inv_step = 1/(numeric_limits<Real>::epsilon)();
|
||||
return f(complex<Real>(x, step)).imag()*inv_step;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <unsigned>
|
||||
struct fd_tag {};
|
||||
|
||||
template<class F, class Real>
|
||||
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<Real>::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<class F, class Real>
|
||||
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<Real>::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<Real>(1) / static_cast<Real>(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<class F, class Real>
|
||||
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<Real>::epsilon)();
|
||||
// Error bound ~eps^4/5
|
||||
Real h = pow(Real(11.25)*eps, static_cast<Real>(1) / static_cast<Real>(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<class F, class Real>
|
||||
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<Real>::epsilon)();
|
||||
// Error bound ~eps^6/7
|
||||
// Error: h^6f^(7)(x)/140 + 5|f(x)|eps/h
|
||||
Real h = pow(eps / 168, static_cast<Real>(1) / static_cast<Real>(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<class F, class Real>
|
||||
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<Real>::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<Real>(1) / static_cast<Real>(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<class F, class Real, class tag>
|
||||
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<class F, class Real, size_t order=6>
|
||||
inline Real finite_difference_derivative(const F f, Real x, Real* error = nullptr)
|
||||
{
|
||||
return detail::finite_difference_derivative(f, x, error, detail::fd_tag<order>());
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
#endif
|
||||
591
third-party/boost-math/include/boost/math/differentiation/lanczos_smoothing.hpp
vendored
Normal file
591
third-party/boost-math/include/boost/math/differentiation/lanczos_smoothing.hpp
vendored
Normal file
@ -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 <cmath> // for std::abs
|
||||
#include <cstddef>
|
||||
#include <limits> // to nan initialize
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
|
||||
#include <boost/math/tools/is_standalone.hpp>
|
||||
#ifndef BOOST_MATH_STANDALONE
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR
|
||||
#error "The header <boost/math/norms.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace boost::math::differentiation {
|
||||
|
||||
namespace detail {
|
||||
template <typename Real>
|
||||
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 <class Real>
|
||||
std::vector<Real> interior_velocity_filter(std::size_t n, std::size_t p) {
|
||||
auto dlp = discrete_legendre<Real>(n, 0);
|
||||
std::vector<Real> 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<Real> 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<Real>(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 <class Real>
|
||||
std::vector<Real> boundary_velocity_filter(std::size_t n, std::size_t p, int64_t s)
|
||||
{
|
||||
std::vector<Real> coeffs(p+1, std::numeric_limits<Real>::quiet_NaN());
|
||||
Real sn = Real(s) / Real(n);
|
||||
auto dlp = discrete_legendre<Real>(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<Real> 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<Real>(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 <class Real>
|
||||
std::vector<Real> 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<Real> coeffs(p+1, std::numeric_limits<Real>::quiet_NaN());
|
||||
Real sn = Real(s) / Real(n);
|
||||
auto dlp = discrete_legendre<Real>(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<Real> 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<Real>(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 <typename Real, std::size_t order = 1>
|
||||
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<Real>,
|
||||
"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<Real, float> || std::is_same_v<Real, double>)
|
||||
{
|
||||
auto interior = detail::interior_velocity_filter<long double>(n, approximation_order);
|
||||
m_f.resize(interior.size());
|
||||
for (std::size_t j = 0; j < interior.size(); ++j)
|
||||
{
|
||||
m_f[j] = static_cast<Real>(interior[j])/m_dt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_f = detail::interior_velocity_filter<Real>(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<Real, float> || std::is_same_v<Real, double>)
|
||||
{
|
||||
int64_t s = static_cast<int64_t>(i) - static_cast<int64_t>(n);
|
||||
auto bf = detail::boundary_velocity_filter<long double>(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<Real>(bf[j])/m_dt;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int64_t s = static_cast<int64_t>(i) - static_cast<int64_t>(n);
|
||||
m_boundary_filters[i] = detail::boundary_velocity_filter<Real>(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<Real, double> || std::is_same_v<Real, float>)
|
||||
{
|
||||
auto f = detail::acceleration_filter<long double>(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<Real>(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<int64_t>(i) - static_cast<int64_t>(n);
|
||||
auto bf = detail::acceleration_filter<long double>(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<Real>(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<Real>(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<int64_t>(i) - static_cast<int64_t>(n);
|
||||
m_boundary_filters[i] = detail::acceleration_filter<Real>(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<class RandomAccessContainer>
|
||||
Real operator()(RandomAccessContainer const & v, std::size_t i) const
|
||||
{
|
||||
static_assert(std::is_same_v<typename RandomAccessContainer::value_type, Real>,
|
||||
"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<Real>::quiet_NaN();
|
||||
}
|
||||
|
||||
template<class RandomAccessContainer>
|
||||
void operator()(RandomAccessContainer const & v, RandomAccessContainer & w) const
|
||||
{
|
||||
static_assert(std::is_same_v<typename RandomAccessContainer::value_type, Real>,
|
||||
"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<class RandomAccessContainer>
|
||||
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<Real> m_f;
|
||||
std::vector<std::vector<Real>> m_boundary_filters;
|
||||
Real m_dt;
|
||||
};
|
||||
|
||||
} // namespaces
|
||||
#endif
|
||||
58
third-party/boost-math/include/boost/math/distributions.hpp
vendored
Normal file
58
third-party/boost-math/include/boost/math/distributions.hpp
vendored
Normal file
@ -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 <boost/math/distributions/arcsine.hpp>
|
||||
#include <boost/math/distributions/bernoulli.hpp>
|
||||
#include <boost/math/distributions/beta.hpp>
|
||||
#include <boost/math/distributions/binomial.hpp>
|
||||
#include <boost/math/distributions/cauchy.hpp>
|
||||
#include <boost/math/distributions/chi_squared.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/exponential.hpp>
|
||||
#include <boost/math/distributions/extreme_value.hpp>
|
||||
#include <boost/math/distributions/fisher_f.hpp>
|
||||
#include <boost/math/distributions/gamma.hpp>
|
||||
#include <boost/math/distributions/geometric.hpp>
|
||||
#include <boost/math/distributions/holtsmark.hpp>
|
||||
#include <boost/math/distributions/hyperexponential.hpp>
|
||||
#include <boost/math/distributions/hypergeometric.hpp>
|
||||
#include <boost/math/distributions/inverse_chi_squared.hpp>
|
||||
#include <boost/math/distributions/inverse_gamma.hpp>
|
||||
#include <boost/math/distributions/inverse_gaussian.hpp>
|
||||
#include <boost/math/distributions/kolmogorov_smirnov.hpp>
|
||||
#include <boost/math/distributions/landau.hpp>
|
||||
#include <boost/math/distributions/laplace.hpp>
|
||||
#include <boost/math/distributions/logistic.hpp>
|
||||
#include <boost/math/distributions/lognormal.hpp>
|
||||
#include <boost/math/distributions/mapairy.hpp>
|
||||
#include <boost/math/distributions/negative_binomial.hpp>
|
||||
#include <boost/math/distributions/non_central_chi_squared.hpp>
|
||||
#include <boost/math/distributions/non_central_beta.hpp>
|
||||
#include <boost/math/distributions/non_central_f.hpp>
|
||||
#include <boost/math/distributions/non_central_t.hpp>
|
||||
#include <boost/math/distributions/normal.hpp>
|
||||
#include <boost/math/distributions/pareto.hpp>
|
||||
#include <boost/math/distributions/poisson.hpp>
|
||||
#include <boost/math/distributions/rayleigh.hpp>
|
||||
#include <boost/math/distributions/saspoint5.hpp>
|
||||
#include <boost/math/distributions/skew_normal.hpp>
|
||||
#include <boost/math/distributions/students_t.hpp>
|
||||
#include <boost/math/distributions/triangular.hpp>
|
||||
#include <boost/math/distributions/uniform.hpp>
|
||||
#include <boost/math/distributions/weibull.hpp>
|
||||
#include <boost/math/distributions/find_scale.hpp>
|
||||
#include <boost/math/distributions/find_location.hpp>
|
||||
|
||||
#endif // BOOST_MATH_DISTRIBUTIONS_HPP
|
||||
|
||||
548
third-party/boost-math/include/boost/math/distributions/arcsine.hpp
vendored
Normal file
548
third-party/boost-math/include/boost/math/distributions/arcsine.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/tuple.hpp>
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/distributions/complement.hpp> // complements.
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks.
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
|
||||
#ifndef BOOST_MATH_HAS_NVRTC
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
#include <exception> // 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 <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"x_min argument is %1%, but must be finite !", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_x_min
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"x_max argument is %1%, but must be finite !", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_x_max
|
||||
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
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 <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_prob
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
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<RealType>(
|
||||
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<double> 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 <class RealType, class Policy>
|
||||
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 <class RealType, class Policy>
|
||||
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 <class RealType, class Policy>
|
||||
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 RealType = double, class Policy = policies::policy<> >
|
||||
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 RealType, class Policy> class arcsine_distribution
|
||||
|
||||
// Convenient typedef to construct double version.
|
||||
typedef arcsine_distribution<double> arcsine;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
arcsine_distribution(RealType)->arcsine_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
arcsine_distribution(RealType, RealType)->arcsine_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const arcsine_distribution<RealType, Policy>& dist)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return boost::math::pair<RealType, RealType>(static_cast<RealType>(dist.x_min()), static_cast<RealType>(dist.x_max()));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const arcsine_distribution<RealType, Policy>& 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<RealType, RealType>(static_cast<RealType>(dist.x_min()), static_cast<RealType>(dist.x_max()));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType mean(const arcsine_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType variance(const arcsine_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType mode(const arcsine_distribution<RealType, Policy>& /* 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<RealType>(
|
||||
"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<RealType>::quiet_NaN(), Policy());
|
||||
} // mode
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType median(const arcsine_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType skewness(const arcsine_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const arcsine_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const arcsine_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType pdf(const arcsine_distribution<RealType, Policy>& 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<RealType>(1) / (pi<RealType>() * sqrt((x - lo) * (hi - x)));
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType cdf(const arcsine_distribution<RealType, Policy>& 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<RealType>(2) * asin(sqrt((x - x_min) / (x_max - x_min))) / pi<RealType>();
|
||||
return result;
|
||||
} // arcsine cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<arcsine_distribution<RealType, Policy>, 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<RealType, Policy> 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<RealType>(2) * asin(sqrt((x - x_min) / (x_max - x_min))) / pi<RealType>();
|
||||
// is less accurate, so use acos instead of asin for complement.
|
||||
result = static_cast<RealType>(2) * acos(sqrt((x - x_min) / (x_max - x_min))) / pi<RealType>();
|
||||
return result;
|
||||
} // arcsine ccdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType quantile(const arcsine_distribution<RealType, Policy>& 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<RealType>() * p);
|
||||
RealType sin2hpip2 = sin2hpip * sin2hpip;
|
||||
result = -x_min * sin2hpip2 + x_min + x_max * sin2hpip2;
|
||||
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<arcsine_distribution<RealType, Policy>, 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<RealType, Policy>& 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<RealType>() * p); loses accuracy, so use a cos alternative instead.
|
||||
//result = cos(half_pi<RealType>() * q); // for arcsine(0,1)
|
||||
//result = result * result;
|
||||
// For generalized arcsine:
|
||||
RealType cos2hpip = cos(half_pi<RealType>() * 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 <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#if defined (BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MATH_DIST_ARCSINE_HPP
|
||||
349
third-party/boost-math/include/boost/math/distributions/bernoulli.hpp
vendored
Normal file
349
third-party/boost-math/include/boost/math/distributions/bernoulli.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/tuple.hpp>
|
||||
#include <boost/math/tools/type_traits.hpp>
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/distributions/complement.hpp> // complements
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
|
||||
#ifndef BOOST_MATH_HAS_NVRTC
|
||||
#include <utility>
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
namespace bernoulli_detail
|
||||
{
|
||||
// Common error checking routines for bernoulli distribution functions:
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, Policy());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline bool check_dist(const char* , const RealType& , RealType* , const Policy& /* pol */, const boost::math::false_type&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
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<Policy>::type());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<Policy>::type()) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!(boost::math::isfinite)(k) || !((k == 0) || (k == 1)))
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Number of successes argument is %1%, but must be 0 or 1 !", k, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
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<Policy>::type()) && detail::check_probability(function, prob, result, Policy())) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace bernoulli_detail
|
||||
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
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 RealType> class bernoulli_distribution
|
||||
|
||||
typedef bernoulli_distribution<double> bernoulli;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
bernoulli_distribution(RealType)->bernoulli_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const bernoulli_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable k = {0, 1}.
|
||||
using boost::math::tools::max_value;
|
||||
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const bernoulli_distribution<RealType, Policy>& /* 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<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType mean(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of bernoulli distribution = p (n = 1).
|
||||
return dist.success_fraction();
|
||||
} // mean
|
||||
|
||||
// Rely on derived_accessors quantile(half)
|
||||
//template <class RealType>
|
||||
//inline RealType median(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
//{ // Median of bernoulli distribution is not defined.
|
||||
// return tools::domain_error<RealType>(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits<RealType>::quiet_NaN());
|
||||
//} // median
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType variance(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of bernoulli distribution =p * q.
|
||||
return dist.success_fraction() * (1 - dist.success_fraction());
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED RealType pdf(const bernoulli_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType cdf(const bernoulli_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<bernoulli_distribution<RealType, Policy>, RealType>& c)
|
||||
{ // Complemented Cumulative Distribution Function bernoulli.
|
||||
RealType const& k = c.param;
|
||||
bernoulli_distribution<RealType, Policy> 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType quantile(const bernoulli_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<bernoulli_distribution<RealType, Policy>, 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<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType mode(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return static_cast<RealType>((dist.success_fraction() <= 0.5) ? 0 : 1); // p = 0.5 can be 0 or 1
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType skewness(const bernoulli_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING; // Aid ADL for sqrt.
|
||||
RealType p = dist.success_fraction();
|
||||
return (1 - 2 * p) / sqrt(p * (1 - p));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const bernoulli_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const bernoulli_distribution<RealType, Policy>& 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 <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_BERNOULLI_HPP
|
||||
|
||||
|
||||
|
||||
584
third-party/boost-math/include/boost/math/distributions/beta.hpp
vendored
Normal file
584
third-party/boost-math/include/boost/math/distributions/beta.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/tuple.hpp>
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/beta.hpp> // for beta.
|
||||
#include <boost/math/distributions/complement.hpp> // complements.
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/tools/roots.hpp> // for root finding.
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
|
||||
#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 <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Alpha argument is %1%, but must be > 0 !", alpha, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_alpha
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Beta argument is %1%, but must be > 0 !", beta, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_beta
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_prob
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"x argument is %1%, but must be >= 0 and <= 1 !", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_x
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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 <class RealType, class Policy>
|
||||
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 <class RealType, class Policy>
|
||||
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 <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"mean argument is %1%, but must be > 0 !", mean, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_mean
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"variance argument is %1%, but must be > 0 !", variance, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_variance
|
||||
} // namespace beta_detail
|
||||
|
||||
// typedef beta_distribution<double> beta;
|
||||
// is deliberately NOT included to avoid a name clash with the beta function.
|
||||
// Use beta_distribution<> mybeta(...) to construct type double.
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
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<RealType>(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<RealType>(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 RealType, class Policy> class beta_distribution
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
beta_distribution(RealType)->beta_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
beta_distribution(RealType, RealType)->beta_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const beta_distribution<RealType, Policy>& /* dist */)
|
||||
{ // Range of permissible values for random variable x.
|
||||
using boost::math::tools::max_value;
|
||||
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const beta_distribution<RealType, Policy>& /* 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<RealType, RealType>(static_cast<RealType>(0), static_cast<RealType>(1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType mean(const beta_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of beta distribution = np.
|
||||
return dist.alpha() / (dist.alpha() + dist.beta());
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType variance(const beta_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType mode(const beta_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
constexpr auto function = "boost::math::mode(beta_distribution<%1%> const&)";
|
||||
|
||||
RealType result;
|
||||
if ((dist.alpha() <= 1))
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"mode undefined for alpha = %1%, must be > 1!", dist.alpha(), Policy());
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((dist.beta() <= 1))
|
||||
{
|
||||
result = policies::raise_domain_error<RealType>(
|
||||
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 <class RealType, class Policy>
|
||||
//inline RealType median(const beta_distribution<RealType, Policy>& dist)
|
||||
//{ // Median of beta distribution is not defined.
|
||||
// return tools::domain_error<RealType>(function, "Median is not implemented, result is %1%!", std::numeric_limits<RealType>::quiet_NaN());
|
||||
//} // median
|
||||
|
||||
//But WILL be provided by the derived accessor as quantile(0.5).
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType skewness(const beta_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const beta_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const beta_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return 3 + kurtosis_excess(dist);
|
||||
} // kurtosis
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType pdf(const beta_distribution<RealType, Policy>& 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<RealType>(1 / beta(a, b));
|
||||
}
|
||||
else if (a < 1)
|
||||
{
|
||||
policies::raise_overflow_error<RealType>(function, nullptr, Policy());
|
||||
}
|
||||
else
|
||||
{
|
||||
return RealType(0);
|
||||
}
|
||||
}
|
||||
else if (x == 1)
|
||||
{
|
||||
if (b == 1)
|
||||
{
|
||||
return static_cast<RealType>(1 / beta(a, b));
|
||||
}
|
||||
else if (b < 1)
|
||||
{
|
||||
policies::raise_overflow_error<RealType>(function, nullptr, Policy());
|
||||
}
|
||||
else
|
||||
{
|
||||
return RealType(0);
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<RealType>(ibeta_derivative(a, b, x, Policy()));
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType cdf(const beta_distribution<RealType, Policy>& 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<RealType>(ibeta(a, b, x, Policy()));
|
||||
} // beta cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<beta_distribution<RealType, Policy>, 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<RealType, Policy> 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<RealType>(ibetac(a, b, x, Policy()));
|
||||
} // beta cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType quantile(const beta_distribution<RealType, Policy>& 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<RealType>(ibeta_inv(a, b, p, static_cast<RealType*>(nullptr), Policy()));
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<beta_distribution<RealType, Policy>, 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<RealType, Policy>& 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<RealType>(ibetac_inv(a, b, q, static_cast<RealType*>(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 <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#if defined (BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_MATH_DIST_BETA_HPP
|
||||
|
||||
|
||||
729
third-party/boost-math/include/boost/math/distributions/binomial.hpp
vendored
Normal file
729
third-party/boost-math/include/boost/math/distributions/binomial.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/tuple.hpp>
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/beta.hpp> // for incomplete beta.
|
||||
#include <boost/math/distributions/complement.hpp> // complements
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/distributions/detail/inv_discrete_quantile.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp> // isnan.
|
||||
#include <boost/math/tools/roots.hpp> // for root finding.
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class binomial_distribution;
|
||||
|
||||
namespace binomial_detail{
|
||||
// common error checking routines for binomial distribution functions:
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Number of Trials argument is %1%, but must be >= 0 !", N, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
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 <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Number of Successes argument is %1%, but must be >= 0 !", k, pol);
|
||||
return false;
|
||||
}
|
||||
if(k > N)
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
function,
|
||||
"Number of Successes argument is %1%, but must be <= Number of Trials !", k, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class RealType, class Policy>
|
||||
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 <class T, class Policy>
|
||||
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<T>();
|
||||
// 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<T>())
|
||||
return sqrt(tools::min_value<T>());
|
||||
if(w > n)
|
||||
return n;
|
||||
return w;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED RealType quantile_imp(const binomial_distribution<RealType, Policy>& 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<Policy>();
|
||||
result = detail::inverse_discrete_quantile(
|
||||
dist,
|
||||
comp ? q : p,
|
||||
comp,
|
||||
guess,
|
||||
factor,
|
||||
RealType(1),
|
||||
discrete_quantile_type(),
|
||||
max_iter);
|
||||
return result;
|
||||
} // quantile
|
||||
|
||||
}
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
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<RealType*>(nullptr), Policy())
|
||||
: ibeta_inv(successes + 0.5f, trials - successes + 0.5f, probability, static_cast<RealType*>(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<RealType*>(nullptr), Policy())
|
||||
: ibetac_inv(successes + 0.5f, trials - successes + 0.5f, probability, static_cast<RealType*>(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 RealType, class Policy> class binomial_distribution
|
||||
|
||||
typedef binomial_distribution<> binomial;
|
||||
// typedef binomial_distribution<double> binomial;
|
||||
// IS now included since no longer a name clash with function binomial.
|
||||
//typedef binomial_distribution<double> binomial; // Reserved name of type double.
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
binomial_distribution(RealType)->binomial_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
binomial_distribution(RealType,RealType)->binomial_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED const boost::math::pair<RealType, RealType> range(const binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Range of permissible values for random variable k.
|
||||
using boost::math::tools::max_value;
|
||||
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), dist.trials());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED const boost::math::pair<RealType, RealType> support(const binomial_distribution<RealType, Policy>& 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<RealType, RealType>(static_cast<RealType>(0), dist.trials());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED inline RealType mean(const binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of Binomial distribution = np.
|
||||
return dist.trials() * dist.success_fraction();
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED inline RealType variance(const binomial_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of Binomial distribution = np(1-p).
|
||||
return dist.trials() * dist.success_fraction() * (1 - dist.success_fraction());
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED RealType pdf(const binomial_distribution<RealType, Policy>& 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<RealType>(k == 0 ? 1 : 0);
|
||||
}
|
||||
if (dist.success_fraction() == 1)
|
||||
{ // probability of n successes is 1:
|
||||
return static_cast<RealType>(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 <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED inline RealType cdf(const binomial_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED inline RealType cdf(const complemented2_type<binomial_distribution<RealType, Policy>, 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<RealType, Policy> 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 <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED inline RealType quantile(const binomial_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
return binomial_detail::quantile_imp(dist, p, RealType(1-p), false);
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED RealType quantile(const complemented2_type<binomial_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
return binomial_detail::quantile_imp(c.dist, RealType(1-c.param), c.param, true);
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED inline RealType mode(const binomial_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // ADL of std functions.
|
||||
RealType p = dist.success_fraction();
|
||||
RealType n = dist.trials();
|
||||
return floor(p * (n + 1));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED inline RealType median(const binomial_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED inline RealType skewness(const binomial_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED inline RealType kurtosis(const binomial_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType p = dist.success_fraction();
|
||||
RealType n = dist.trials();
|
||||
return 3 - 6 / n + 1 / (n * p * (1 - p));
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_CUDA_ENABLED inline RealType kurtosis_excess(const binomial_distribution<RealType, Policy>& 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 <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_SPECIAL_BINOMIAL_HPP
|
||||
|
||||
|
||||
379
third-party/boost-math/include/boost/math/distributions/cauchy.hpp
vendored
Normal file
379
third-party/boost-math/include/boost/math/distributions/cauchy.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/tuple.hpp>
|
||||
#include <boost/math/tools/numeric_limits.hpp>
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
#include <boost/math/tools/promotion.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/distributions/complement.hpp>
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp>
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
|
||||
#ifndef BOOST_MATH_HAS_NVRTC
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <utility>
|
||||
#include <cmath>
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
class cauchy_distribution;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED RealType cdf_imp(const cauchy_distribution<RealType, Policy>& 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<RealType>())
|
||||
{
|
||||
return static_cast<RealType>((complement) ? 0 : 1);
|
||||
}
|
||||
if(x < -tools::max_value<RealType>())
|
||||
{
|
||||
return static_cast<RealType>((complement) ? 1 : 0);
|
||||
}
|
||||
#else
|
||||
if(boost::math::numeric_limits<RealType>::has_infinity && x == boost::math::numeric_limits<RealType>::infinity())
|
||||
{ // cdf +infinity is unity.
|
||||
return static_cast<RealType>((complement) ? 0 : 1);
|
||||
}
|
||||
if(boost::math::numeric_limits<RealType>::has_infinity && x == -boost::math::numeric_limits<RealType>::infinity())
|
||||
{ // cdf -infinity is zero.
|
||||
return static_cast<RealType>((complement) ? 1 : 0);
|
||||
}
|
||||
#endif
|
||||
if(false == detail::check_x(function, x, &result, Policy()))
|
||||
{ // Catches x == NaN
|
||||
return result;
|
||||
}
|
||||
RealType x_std = static_cast<RealType>((complement) ? 1 : -1)*(x - location) / scale;
|
||||
return atan2(static_cast<RealType>(1), x_std) / constants::pi<RealType>();
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED RealType quantile_imp(
|
||||
const cauchy_distribution<RealType, Policy>& 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<RealType>(function, 0, Policy());
|
||||
}
|
||||
if(p == 0)
|
||||
{
|
||||
return (complement ? 1 : -1) * policies::raise_overflow_error<RealType>(function, 0, Policy());
|
||||
}
|
||||
|
||||
if(p > 0.5)
|
||||
{
|
||||
p = p - 1;
|
||||
}
|
||||
if(p == 0.5) // special case:
|
||||
{
|
||||
return location;
|
||||
}
|
||||
result = -scale / tan(constants::pi<RealType>() * p);
|
||||
return complement ? RealType(location - result) : RealType(location + result);
|
||||
} // quantile
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
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<double> cauchy;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
cauchy_distribution(RealType)->cauchy_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
template <class RealType>
|
||||
cauchy_distribution(RealType,RealType)->cauchy_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> range(const cauchy_distribution<RealType, Policy>&)
|
||||
{ // Range of permissible values for random variable x.
|
||||
BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits<RealType>::has_infinity)
|
||||
{
|
||||
return boost::math::pair<RealType, RealType>(-boost::math::numeric_limits<RealType>::infinity(), boost::math::numeric_limits<RealType>::infinity()); // - to + infinity.
|
||||
}
|
||||
else
|
||||
{ // Can only use max_value.
|
||||
using boost::math::tools::max_value;
|
||||
return boost::math::pair<RealType, RealType>(-max_value<RealType>(), max_value<RealType>()); // - to + max.
|
||||
}
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline const boost::math::pair<RealType, RealType> support(const cauchy_distribution<RealType, Policy>& )
|
||||
{ // 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<RealType>::has_infinity)
|
||||
{
|
||||
return boost::math::pair<RealType, RealType>(-boost::math::numeric_limits<RealType>::infinity(), boost::math::numeric_limits<RealType>::infinity()); // - to + infinity.
|
||||
}
|
||||
else
|
||||
{ // Can only use max_value.
|
||||
using boost::math::tools::max_value;
|
||||
return boost::math::pair<RealType, RealType>(-tools::max_value<RealType>(), max_value<RealType>()); // - to + max.
|
||||
}
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType pdf(const cauchy_distribution<RealType, Policy>& 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<RealType>::has_infinity && abs(x) == boost::math::numeric_limits<RealType>::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<RealType>() * scale * (1 + xs * xs));
|
||||
return result;
|
||||
} // pdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType cdf(const cauchy_distribution<RealType, Policy>& dist, const RealType& x)
|
||||
{
|
||||
return detail::cdf_imp(dist, x, false);
|
||||
} // cdf
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType quantile(const cauchy_distribution<RealType, Policy>& dist, const RealType& p)
|
||||
{
|
||||
return detail::quantile_imp(dist, p, false);
|
||||
} // quantile
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<cauchy_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
return detail::cdf_imp(c.dist, c.param, true);
|
||||
} // cdf complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<cauchy_distribution<RealType, Policy>, RealType>& c)
|
||||
{
|
||||
return detail::quantile_imp(c.dist, c.param, true);
|
||||
} // quantile complement
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType mean(const cauchy_distribution<RealType, Policy>&)
|
||||
{ // 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<RealType>(
|
||||
"boost::math::mean(cauchy<%1%>&)",
|
||||
"The Cauchy distribution does not have a mean: "
|
||||
"the only possible return value is %1%.",
|
||||
boost::math::numeric_limits<RealType>::quiet_NaN(), Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType variance(const cauchy_distribution<RealType, Policy>& /*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<RealType>(
|
||||
"boost::math::variance(cauchy<%1%>&)",
|
||||
"The Cauchy distribution does not have a variance: "
|
||||
"the only possible return value is %1%.",
|
||||
boost::math::numeric_limits<RealType>::quiet_NaN(), Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType mode(const cauchy_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType median(const cauchy_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
return dist.location();
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType skewness(const cauchy_distribution<RealType, Policy>& /*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<RealType>(
|
||||
"boost::math::skewness(cauchy<%1%>&)",
|
||||
"The Cauchy distribution does not have a skewness: "
|
||||
"the only possible return value is %1%.",
|
||||
boost::math::numeric_limits<RealType>::quiet_NaN(), Policy()); // infinity?
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const cauchy_distribution<RealType, Policy>& /*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<RealType>(
|
||||
"boost::math::kurtosis(cauchy<%1%>&)",
|
||||
"The Cauchy distribution does not have a kurtosis: "
|
||||
"the only possible return value is %1%.",
|
||||
boost::math::numeric_limits<RealType>::quiet_NaN(), Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const cauchy_distribution<RealType, Policy>& /*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<RealType>(
|
||||
"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<RealType>::quiet_NaN(), Policy());
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType entropy(const cauchy_distribution<RealType, Policy> & dist)
|
||||
{
|
||||
using std::log;
|
||||
return log(2*constants::two_pi<RealType>()*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 <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_STATS_CAUCHY_HPP
|
||||
347
third-party/boost-math/include/boost/math/distributions/chi_squared.hpp
vendored
Normal file
347
third-party/boost-math/include/boost/math/distributions/chi_squared.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/type_traits.hpp>
|
||||
#include <boost/math/tools/numeric_limits.hpp>
|
||||
#include <boost/math/tools/cstdint.hpp>
|
||||
#include <boost/math/tools/toms748_solve.hpp>
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp> // for incomplete beta.
|
||||
#include <boost/math/distributions/complement.hpp> // complements
|
||||
#include <boost/math/distributions/detail/common_error_handling.hpp> // error checks
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class RealType = double, class Policy = policies::policy<> >
|
||||
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<double>;
|
||||
|
||||
#ifdef __cpp_deduction_guides
|
||||
template <class RealType>
|
||||
chi_squared_distribution(RealType)->chi_squared_distribution<typename boost::math::tools::promote_args<RealType>::type>;
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127)
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline boost::math::pair<RealType, RealType> range(const chi_squared_distribution<RealType, Policy>& /*dist*/)
|
||||
{ // Range of permissible values for random variable x.
|
||||
BOOST_MATH_IF_CONSTEXPR (boost::math::numeric_limits<RealType>::has_infinity)
|
||||
{
|
||||
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), boost::math::numeric_limits<RealType>::infinity()); // 0 to + infinity.
|
||||
}
|
||||
else
|
||||
{
|
||||
using boost::math::tools::max_value;
|
||||
return boost::math::pair<RealType, RealType>(static_cast<RealType>(0), max_value<RealType>()); // 0 to + max.
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline boost::math::pair<RealType, RealType> support(const chi_squared_distribution<RealType, Policy>& /*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<RealType, RealType>(static_cast<RealType>(0), tools::max_value<RealType>()); // 0 to + infinity.
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED RealType pdf(const chi_squared_distribution<RealType, Policy>& 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<RealType>(
|
||||
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<RealType>(
|
||||
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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType cdf(const chi_squared_distribution<RealType, Policy>& 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<RealType>(
|
||||
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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType quantile(const chi_squared_distribution<RealType, Policy>& 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType cdf(const complemented2_type<chi_squared_distribution<RealType, Policy>, 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<RealType>(
|
||||
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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType quantile(const complemented2_type<chi_squared_distribution<RealType, Policy>, 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType mean(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // Mean of Chi-Squared distribution = v.
|
||||
return dist.degrees_of_freedom();
|
||||
} // mean
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType variance(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{ // Variance of Chi-Squared distribution = 2v.
|
||||
return 2 * dist.degrees_of_freedom();
|
||||
} // variance
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType mode(const chi_squared_distribution<RealType, Policy>& 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<RealType>(
|
||||
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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType skewness(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
BOOST_MATH_STD_USING // For ADL
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
return sqrt (8 / df);
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType kurtosis(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
return 3 + 12 / df;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED inline RealType kurtosis_excess(const chi_squared_distribution<RealType, Policy>& dist)
|
||||
{
|
||||
RealType df = dist.degrees_of_freedom();
|
||||
return 12 / df;
|
||||
}
|
||||
|
||||
//
|
||||
// Parameter estimation comes last:
|
||||
//
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>())
|
||||
return 1;
|
||||
chi_squared_distribution<RealType, Policy> 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 <class RealType, class Policy>
|
||||
BOOST_MATH_GPU_ENABLED RealType chi_squared_distribution<RealType, Policy>::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<RealType, Policy> f(alpha, beta, variance, difference_from_variance);
|
||||
tools::eps_tolerance<RealType> tol(policies::digits<RealType, Policy>());
|
||||
boost::math::uintmax_t max_iter = policies::get_max_root_iterations<Policy>();
|
||||
boost::math::pair<RealType, RealType> 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<Policy>())
|
||||
{
|
||||
policies::raise_evaluation_error<RealType>(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 <boost/math/distributions/detail/derived_accessors.hpp>
|
||||
|
||||
#endif // BOOST_MATH_DISTRIBUTIONS_CHI_SQUARED_HPP
|
||||
198
third-party/boost-math/include/boost/math/distributions/complement.hpp
vendored
Normal file
198
third-party/boost-math/include/boost/math/distributions/complement.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
|
||||
//
|
||||
// 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 <class Dist, class RealType>
|
||||
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 <class Dist, class RealType1, class RealType2>
|
||||
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 <class Dist, class RealType1, class RealType2, class RealType3>
|
||||
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 <class Dist, class RealType1, class RealType2, class RealType3, class RealType4>
|
||||
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 <class Dist, class RealType1, class RealType2, class RealType3, class RealType4, class RealType5>
|
||||
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 <class Dist, class RealType1, class RealType2, class RealType3, class RealType4, class RealType5, class RealType6>
|
||||
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 <class Dist, class RealType>
|
||||
BOOST_MATH_GPU_ENABLED inline complemented2_type<Dist, RealType> complement(const Dist& d, const RealType& r)
|
||||
{
|
||||
return complemented2_type<Dist, RealType>(d, r);
|
||||
}
|
||||
|
||||
template <class Dist, class RealType1, class RealType2>
|
||||
BOOST_MATH_GPU_ENABLED inline complemented3_type<Dist, RealType1, RealType2> complement(const Dist& d, const RealType1& r1, const RealType2& r2)
|
||||
{
|
||||
return complemented3_type<Dist, RealType1, RealType2>(d, r1, r2);
|
||||
}
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3>
|
||||
BOOST_MATH_GPU_ENABLED inline complemented4_type<Dist, RealType1, RealType2, RealType3> complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3)
|
||||
{
|
||||
return complemented4_type<Dist, RealType1, RealType2, RealType3>(d, r1, r2, r3);
|
||||
}
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4>
|
||||
BOOST_MATH_GPU_ENABLED inline complemented5_type<Dist, RealType1, RealType2, RealType3, RealType4> complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4)
|
||||
{
|
||||
return complemented5_type<Dist, RealType1, RealType2, RealType3, RealType4>(d, r1, r2, r3, r4);
|
||||
}
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4, class RealType5>
|
||||
BOOST_MATH_GPU_ENABLED inline complemented6_type<Dist, RealType1, RealType2, RealType3, RealType4, RealType5> complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4, const RealType5& r5)
|
||||
{
|
||||
return complemented6_type<Dist, RealType1, RealType2, RealType3, RealType4, RealType5>(d, r1, r2, r3, r4, r5);
|
||||
}
|
||||
|
||||
template <class Dist, class RealType1, class RealType2, class RealType3, class RealType4, class RealType5, class RealType6>
|
||||
BOOST_MATH_GPU_ENABLED inline complemented7_type<Dist, RealType1, RealType2, RealType3, RealType4, RealType5, RealType6> 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<Dist, RealType1, RealType2, RealType3, RealType4, RealType5, RealType6>(d, r1, r2, r3, r4, r5, r6);
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_STATS_COMPLEMENT_HPP
|
||||
|
||||
228
third-party/boost-math/include/boost/math/distributions/detail/common_error_handling.hpp
vendored
Normal file
228
third-party/boost-math/include/boost/math/distributions/detail/common_error_handling.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/numeric_limits.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
// 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 <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Probability argument is %1%, but must be >= 0 and <= 1 !", prob, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Degrees of freedom argument is %1%, but must be > 0 !", df, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Degrees of freedom argument is %1%, but must be > 0 !", df, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // check_df_gt0_to_inf
|
||||
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Scale parameter is %1%, but must be > 0 !", scale, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Location parameter is %1%, but must be finite!", location, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
function,
|
||||
"Random variate x is %1%, but must be finite!", x, pol);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} // bool check_x
|
||||
|
||||
template <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
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 <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
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 <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
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 <class RealType, class Policy>
|
||||
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<RealType>((boost::math::numeric_limits<long long>::max)()) - boost::math::policies::get_max_root_iterations<Policy>();
|
||||
|
||||
if((ncp < 0) || !(boost::math::isfinite)(ncp) || ncp > upper_limit)
|
||||
{
|
||||
*result = policies::raise_domain_error<RealType>(
|
||||
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 <class RealType, class Policy>
|
||||
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<RealType>(
|
||||
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
|
||||
190
third-party/boost-math/include/boost/math/distributions/detail/derived_accessors.hpp
vendored
Normal file
190
third-party/boost-math/include/boost/math/distributions/detail/derived_accessors.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/assert.hpp>
|
||||
|
||||
#ifndef BOOST_MATH_HAS_NVRTC
|
||||
#include <cmath>
|
||||
#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 <class Distribution>
|
||||
BOOST_MATH_GPU_ENABLED typename Distribution::value_type variance(const Distribution& dist);
|
||||
|
||||
template <class Distribution>
|
||||
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 <class Distribution>
|
||||
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 <class Distribution, class RealType>
|
||||
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<value_type>())
|
||||
return policies::raise_overflow_error<value_type>(
|
||||
"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 <class Distribution, class RealType>
|
||||
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 <class Distribution>
|
||||
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<value_type>()))
|
||||
{ // Checks too that m is not zero,
|
||||
return policies::raise_overflow_error<value_type>("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 <class Distribution, class RealType>
|
||||
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<value_type>(x));
|
||||
}
|
||||
template <class Distribution, class RealType>
|
||||
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<value_type>(x)));
|
||||
}
|
||||
template <class Distribution, class RealType>
|
||||
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<value_type>(x));
|
||||
}
|
||||
template <class Distribution, class Realtype>
|
||||
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<value_type>(x)));
|
||||
}
|
||||
template <class Distribution, class RealType>
|
||||
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<value_type>(x));
|
||||
}
|
||||
/*
|
||||
template <class Distribution, class RealType>
|
||||
inline typename Distribution::value_type chf(const Distribution& dist, const RealType& x)
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return chf(dist, static_cast<value_type>(x));
|
||||
}
|
||||
*/
|
||||
template <class Distribution, class RealType>
|
||||
BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type cdf(const complemented2_type<Distribution, RealType>& c)
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return cdf(complement(c.dist, static_cast<value_type>(c.param)));
|
||||
}
|
||||
|
||||
template <class Distribution, class RealType>
|
||||
BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type logcdf(const complemented2_type<Distribution, RealType>& c)
|
||||
{
|
||||
using std::log;
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return log(cdf(complement(c.dist, static_cast<value_type>(c.param))));
|
||||
}
|
||||
|
||||
template <class Distribution, class RealType>
|
||||
BOOST_MATH_GPU_ENABLED inline typename Distribution::value_type quantile(const complemented2_type<Distribution, RealType>& c)
|
||||
{
|
||||
typedef typename Distribution::value_type value_type;
|
||||
return quantile(complement(c.dist, static_cast<value_type>(c.param)));
|
||||
}
|
||||
|
||||
template <class Dist>
|
||||
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<value_type>(0.5f));
|
||||
}
|
||||
|
||||
} // namespace math
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_STATS_DERIVED_HPP
|
||||
145
third-party/boost-math/include/boost/math/distributions/detail/generic_mode.hpp
vendored
Normal file
145
third-party/boost-math/include/boost/math/distributions/detail/generic_mode.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/cstdint.hpp>
|
||||
#include <boost/math/tools/minima.hpp> // function minimization for mode
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/distributions/fwd.hpp>
|
||||
#include <boost/math/policies/policy.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class Dist>
|
||||
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 <class Dist>
|
||||
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<policy_type>();
|
||||
|
||||
value_type result = tools::brent_find_minima(
|
||||
pdf_minimizer<Dist>(dist),
|
||||
lower_bound,
|
||||
upper_bound,
|
||||
policies::digits<value_type, policy_type>(),
|
||||
max_iter).first;
|
||||
if(max_iter >= policies::get_max_root_iterations<policy_type>())
|
||||
{
|
||||
return policies::raise_evaluation_error<value_type>(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 <class Dist>
|
||||
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<value_type>())
|
||||
return 0;
|
||||
v = pdf(dist, lower_bound);
|
||||
}while(maxval < v);
|
||||
|
||||
boost::math::uintmax_t max_iter = policies::get_max_root_iterations<policy_type>();
|
||||
|
||||
value_type result = tools::brent_find_minima(
|
||||
pdf_minimizer<Dist>(dist),
|
||||
lower_bound,
|
||||
upper_bound,
|
||||
policies::digits<value_type, policy_type>(),
|
||||
max_iter).first;
|
||||
if(max_iter >= policies::get_max_root_iterations<policy_type>())
|
||||
{
|
||||
return policies::raise_evaluation_error<value_type>(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
|
||||
100
third-party/boost-math/include/boost/math/distributions/detail/generic_quantile.hpp
vendored
Normal file
100
third-party/boost-math/include/boost/math/distributions/detail/generic_quantile.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/tuple.hpp>
|
||||
#include <boost/math/tools/cstdint.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class Dist>
|
||||
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 <class T, class Policy>
|
||||
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<T>()))
|
||||
{
|
||||
return policies::raise_underflow_error<T>(function, nullptr, pol);
|
||||
}
|
||||
if(x <= -tools::max_value<T>())
|
||||
{
|
||||
return -policies::raise_overflow_error<T>(function, nullptr, pol);
|
||||
}
|
||||
if(x >= tools::max_value<T>())
|
||||
{
|
||||
return policies::raise_overflow_error<T>(function, nullptr, pol);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class Dist>
|
||||
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<false>,
|
||||
policies::promote_double<false>,
|
||||
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<Dist> f(dist, p, comp);
|
||||
tools::eps_tolerance<value_type> tol(policies::digits<value_type, forwarding_policy>() - 3);
|
||||
boost::math::uintmax_t max_iter = policies::get_max_root_iterations<forwarding_policy>();
|
||||
boost::math::pair<value_type, value_type> 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<forwarding_policy>())
|
||||
{
|
||||
return policies::raise_evaluation_error<value_type>(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
|
||||
|
||||
101
third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_cdf.hpp
vendored
Normal file
101
third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_cdf.hpp
vendored
Normal file
@ -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 <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/distributions/detail/hypergeometric_pdf.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class T, class Policy>
|
||||
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<T>(x, r, n, N, pol);
|
||||
T diff = result;
|
||||
const auto lower_limit = static_cast<std::uint64_t>((std::max)(INT64_C(0), static_cast<std::int64_t>(n + r) - static_cast<std::int64_t>(N)));
|
||||
while(diff > (invert ? T(1) : result) * tools::epsilon<T>())
|
||||
{
|
||||
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<T>(x, r, n, N, pol);
|
||||
T diff = result;
|
||||
while((x <= upper_limit) && (diff > (invert ? T(1) : result) * tools::epsilon<T>()))
|
||||
{
|
||||
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 <class T, class Policy>
|
||||
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<T>::type result_type;
|
||||
typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
value_type result;
|
||||
result = detail::hypergeometric_cdf_imp<value_type>(x, r, n, N, invert, forwarding_policy());
|
||||
if(result > 1)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
if(result < 0)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
return policies::checked_narrowing_cast<result_type, forwarding_policy>(result, "boost::math::hypergeometric_cdf<%1%>(%1%,%1%,%1%,%1%)");
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif
|
||||
|
||||
490
third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_pdf.hpp
vendored
Normal file
490
third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_pdf.hpp
vendored
Normal file
@ -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 <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/special_functions/lanczos.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp>
|
||||
#include <boost/math/special_functions/pow.hpp>
|
||||
#include <boost/math/special_functions/prime.hpp>
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef BOOST_MATH_INSTRUMENT
|
||||
#include <typeinfo>
|
||||
#endif
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class T, class Func>
|
||||
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 <class T>
|
||||
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 <class T, class Lanczos, class Policy>
|
||||
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<T>(Lanczos::g()) + 0.5f,
|
||||
T(r) + static_cast<T>(Lanczos::g()) + 0.5f,
|
||||
T(N - n) + static_cast<T>(Lanczos::g()) + 0.5f,
|
||||
T(N - r) + static_cast<T>(Lanczos::g()) + 0.5f,
|
||||
1 / (T(N) + static_cast<T>(Lanczos::g()) + 0.5f),
|
||||
1 / (T(x) + static_cast<T>(Lanczos::g()) + 0.5f),
|
||||
1 / (T(n - x) + static_cast<T>(Lanczos::g()) + 0.5f),
|
||||
1 / (T(r - x) + static_cast<T>(Lanczos::g()) + 0.5f),
|
||||
1 / (T(N - n - r + x) + static_cast<T>(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<T>(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<T>()) && (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<T>(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<T>(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<T>(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<T>(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<T>())
|
||||
return 0; // short circuit further evaluation
|
||||
if(exponents[sorted_indexes[i]] == 1)
|
||||
result *= bases[sorted_indexes[i]] * exp(static_cast<T>(base_e_factors[sorted_indexes[i]]));
|
||||
else if(exponents[sorted_indexes[i]] == 0.5f)
|
||||
result *= sqrt(bases[sorted_indexes[i]] * exp(static_cast<T>(base_e_factors[sorted_indexes[i]])));
|
||||
else
|
||||
result *= pow(bases[sorted_indexes[i]] * exp(static_cast<T>(base_e_factors[sorted_indexes[i]])), exponents[sorted_indexes[i]]);
|
||||
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(result);
|
||||
}
|
||||
|
||||
result *= Lanczos::lanczos_sum_expG_scaled(static_cast<T>(n + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(r + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N - n + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N - r + 1))
|
||||
/
|
||||
( Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(x + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(n - x + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(r - x + 1))
|
||||
* Lanczos::lanczos_sum_expG_scaled(static_cast<T>(N - n - r + x + 1)));
|
||||
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
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 <class T>
|
||||
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<T>(pow(x, ex));
|
||||
#endif
|
||||
}
|
||||
template <class T>
|
||||
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 <class T>
|
||||
T hypergeometric_pdf_prime_loop_imp(hypergeometric_pdf_prime_loop_data& data, hypergeometric_pdf_prime_loop_result_entry<T>& 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<T>(static_cast<T>(data.current_prime), static_cast<int>(prime_powers));
|
||||
if((p > 1) && (tools::max_value<T>() / p < result.value))
|
||||
{
|
||||
//
|
||||
// The next calculation would overflow, use recursion
|
||||
// to sidestep the issue:
|
||||
//
|
||||
hypergeometric_pdf_prime_loop_result_entry<T> t = { p, &result };
|
||||
data.current_prime = prime(static_cast<unsigned>(++data.prime_index));
|
||||
return hypergeometric_pdf_prime_loop_imp<T>(data, t);
|
||||
}
|
||||
if((p < 1) && (tools::min_value<T>() / p > result.value))
|
||||
{
|
||||
//
|
||||
// The next calculation would underflow, use recursion
|
||||
// to sidestep the issue:
|
||||
//
|
||||
hypergeometric_pdf_prime_loop_result_entry<T> t = { p, &result };
|
||||
data.current_prime = prime(static_cast<unsigned>(++data.prime_index));
|
||||
return hypergeometric_pdf_prime_loop_imp<T>(data, t);
|
||||
}
|
||||
result.value *= p;
|
||||
}
|
||||
data.current_prime = prime(static_cast<unsigned>(++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<T> 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 <class T, class Policy>
|
||||
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<T> result = { 1, 0 };
|
||||
hypergeometric_pdf_prime_loop_data data = { x, r, n, N, 0, prime(0) };
|
||||
return hypergeometric_pdf_prime_loop_imp<T>(data, result);
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
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<T>::value);
|
||||
T result = boost::math::unchecked_factorial<T>(static_cast<unsigned>(n));
|
||||
T num[3] = {
|
||||
boost::math::unchecked_factorial<T>(static_cast<unsigned>(r)),
|
||||
boost::math::unchecked_factorial<T>(static_cast<unsigned>(N - n)),
|
||||
boost::math::unchecked_factorial<T>(static_cast<unsigned>(N - r))
|
||||
};
|
||||
T denom[5] = {
|
||||
boost::math::unchecked_factorial<T>(static_cast<unsigned>(N)),
|
||||
boost::math::unchecked_factorial<T>(static_cast<unsigned>(x)),
|
||||
boost::math::unchecked_factorial<T>(static_cast<unsigned>(n - x)),
|
||||
boost::math::unchecked_factorial<T>(static_cast<unsigned>(r - x)),
|
||||
boost::math::unchecked_factorial<T>(static_cast<unsigned>(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 <class T, class Policy>
|
||||
inline typename tools::promote_args<T>::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<T>::type result_type;
|
||||
typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
||||
typedef typename lanczos::lanczos<value_type, Policy>::type evaluation_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::discrete_quantile<>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
value_type result;
|
||||
if(N <= boost::math::max_factorial<value_type>::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<value_type>(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<value_type>(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_type, forwarding_policy>(result, "boost::math::hypergeometric_pdf<%1%>(%1%,%1%,%1%,%1%)");
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif
|
||||
|
||||
245
third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_quantile.hpp
vendored
Normal file
245
third-party/boost-math/include/boost/math/distributions/detail/hypergeometric_quantile.hpp
vendored
Normal file
@ -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 <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/distributions/detail/hypergeometric_pdf.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
template <class T>
|
||||
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<policies::integer_round_down>&)
|
||||
{
|
||||
if((p < cum * fudge_factor) && (x != lbound))
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x-1);
|
||||
return --x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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<policies::integer_round_up>&)
|
||||
{
|
||||
if((cum < p * fudge_factor) && (x != ubound))
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x+1);
|
||||
return ++x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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<policies::integer_round_inwards>&)
|
||||
{
|
||||
if(p >= 0.5)
|
||||
return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
|
||||
return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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<policies::integer_round_outwards>&)
|
||||
{
|
||||
if(p >= 0.5)
|
||||
return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
|
||||
return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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<policies::integer_round_nearest>&)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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<policies::integer_round_down>&)
|
||||
{
|
||||
if((q * fudge_factor > cum) && (x != lbound))
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x-1);
|
||||
return --x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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<policies::integer_round_up>&)
|
||||
{
|
||||
if((q < cum * fudge_factor) && (x != ubound))
|
||||
{
|
||||
BOOST_MATH_INSTRUMENT_VARIABLE(x+1);
|
||||
return ++x;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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<policies::integer_round_inwards>&)
|
||||
{
|
||||
if(q < 0.5)
|
||||
return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
|
||||
return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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<policies::integer_round_outwards>&)
|
||||
{
|
||||
if(q >= 0.5)
|
||||
return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_down>());
|
||||
return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile<policies::integer_round_up>());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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<policies::integer_round_nearest>&)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T, class Policy>
|
||||
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<T>() * ((N <= boost::math::prime(boost::math::max_prime - 1)) ? 50 : 2 * N);
|
||||
std::uint64_t base = static_cast<std::uint64_t>((std::max)(0, static_cast<int>(n + r) - static_cast<int>(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<T>(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<T>(n + 1), pol)
|
||||
+ boost::math::lgamma(static_cast<T>(r + 1), pol)
|
||||
+ boost::math::lgamma(static_cast<T>(N - n + 1), pol)
|
||||
+ boost::math::lgamma(static_cast<T>(N - r + 1), pol)
|
||||
- boost::math::lgamma(static_cast<T>(N + 1), pol)
|
||||
- boost::math::lgamma(static_cast<T>(x + 1), pol)
|
||||
- boost::math::lgamma(static_cast<T>(n - x + 1), pol)
|
||||
- boost::math::lgamma(static_cast<T>(r - x + 1), pol)
|
||||
- boost::math::lgamma(static_cast<T>(N - n - r + x + 1), pol);
|
||||
while (log_pdf < tools::log_min_value<T>())
|
||||
{
|
||||
log_pdf += -log(static_cast<T>(x + 1)) + log(static_cast<T>(n - x)) + log(static_cast<T>(r - x)) - log(static_cast<T>(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<T>(x, r, n, N, pol);
|
||||
}
|
||||
while(result < p)
|
||||
{
|
||||
diff = (diff > tools::min_value<T>() * 8)
|
||||
? T(n - x) * T(r - x) * diff / (T(x + 1) * T(N + x + 1 - n - r))
|
||||
: hypergeometric_pdf<T>(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<T>(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<T>(n + 1), pol)
|
||||
+ boost::math::lgamma(static_cast<T>(r + 1), pol)
|
||||
+ boost::math::lgamma(static_cast<T>(N - n + 1), pol)
|
||||
+ boost::math::lgamma(static_cast<T>(N - r + 1), pol)
|
||||
- boost::math::lgamma(static_cast<T>(N + 1), pol)
|
||||
- boost::math::lgamma(static_cast<T>(x + 1), pol)
|
||||
- boost::math::lgamma(static_cast<T>(n - x + 1), pol)
|
||||
- boost::math::lgamma(static_cast<T>(r - x + 1), pol)
|
||||
- boost::math::lgamma(static_cast<T>(N - n - r + x + 1), pol);
|
||||
while (log_pdf < tools::log_min_value<T>())
|
||||
{
|
||||
log_pdf += log(static_cast<T>(x)) - log(static_cast<T>(n - x + 1)) - log(static_cast<T>(r - x + 1)) + log(static_cast<T>(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<T>(x, r, n, N, pol);
|
||||
}
|
||||
while(result + diff / 2 < q)
|
||||
{
|
||||
result += diff;
|
||||
diff = (diff > tools::min_value<T>() * 8)
|
||||
? x * T(N + x - n - r) * diff / (T(1 + n - x) * T(1 + r - x))
|
||||
: hypergeometric_pdf<T>(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 <class T, class Policy>
|
||||
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<T>::type result_type;
|
||||
typedef typename policies::evaluation<result_type, Policy>::type value_type;
|
||||
typedef typename policies::normalise<
|
||||
Policy,
|
||||
policies::promote_float<false>,
|
||||
policies::promote_double<false>,
|
||||
policies::assert_undefined<> >::type forwarding_policy;
|
||||
|
||||
return detail::hypergeometric_quantile_imp<value_type>(p, q, r, n, N, forwarding_policy());
|
||||
}
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
#endif
|
||||
|
||||
583
third-party/boost-math/include/boost/math/distributions/detail/inv_discrete_quantile.hpp
vendored
Normal file
583
third-party/boost-math/include/boost/math/distributions/detail/inv_discrete_quantile.hpp
vendored
Normal file
@ -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 <boost/math/tools/config.hpp>
|
||||
#include <boost/math/tools/cstdint.hpp>
|
||||
#include <boost/math/tools/precision.hpp>
|
||||
#include <boost/math/tools/toms748_solve.hpp>
|
||||
#include <boost/math/tools/tuple.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace detail{
|
||||
|
||||
//
|
||||
// Functor for root finding algorithm:
|
||||
//
|
||||
template <class Dist>
|
||||
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 <class Real, class Tol>
|
||||
BOOST_MATH_GPU_ENABLED void adjust_bounds(Real& /* a */, Real& /* b */, Tol const& /* tol */){}
|
||||
|
||||
template <class Real>
|
||||
BOOST_MATH_GPU_ENABLED void adjust_bounds(Real& /* a */, Real& b, tools::equal_floor const& /* tol */)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
b -= tools::epsilon<Real>() * b;
|
||||
}
|
||||
|
||||
template <class Real>
|
||||
BOOST_MATH_GPU_ENABLED void adjust_bounds(Real& a, Real& /* b */, tools::equal_ceil const& /* tol */)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
a += tools::epsilon<Real>() * a;
|
||||
}
|
||||
|
||||
template <class Real>
|
||||
BOOST_MATH_GPU_ENABLED void adjust_bounds(Real& a, Real& b, tools::equal_nearest_integer const& /* tol */)
|
||||
{
|
||||
BOOST_MATH_STD_USING
|
||||
a += tools::epsilon<Real>() * a;
|
||||
b -= tools::epsilon<Real>() * b;
|
||||
}
|
||||
//
|
||||
// This is where all the work is done:
|
||||
//
|
||||
template <class Dist, class Tolerance>
|
||||
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<Dist> 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<value_type>())
|
||||
{
|
||||
// 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<value_type>())
|
||||
a = tools::min_value<value_type>();
|
||||
//
|
||||
// Go ahead and find the root:
|
||||
//
|
||||
boost::math::pair<value_type, value_type> r = toms748_solve(f, a, b, fa, fb, tol, count, policy_type());
|
||||
max_iter += count;
|
||||
if (max_iter >= policies::get_max_root_iterations<policy_type>())
|
||||
{
|
||||
return policies::raise_evaluation_error<value_type>(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 <class Dist>
|
||||
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<typename Dist::value_type>()));
|
||||
#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 <class Dist>
|
||||
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<typename Dist::value_type>()));
|
||||
#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 <class Dist>
|
||||
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<policies::real>&,
|
||||
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<typename Dist::value_type>(policies::digits<typename Dist::value_type, typename Dist::policy_type>()),
|
||||
max_iter);
|
||||
}
|
||||
|
||||
template <class Dist>
|
||||
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<policies::integer_round_outwards>&,
|
||||
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 <class Dist>
|
||||
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<policies::integer_round_inwards>&,
|
||||
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 <class Dist>
|
||||
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<policies::integer_round_down>&,
|
||||
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 <class Dist>
|
||||
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<policies::integer_round_up>&,
|
||||
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 <class Dist>
|
||||
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<policies::integer_round_nearest>&,
|
||||
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
|
||||
|
||||
@ -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 <algorithm>
|
||||
#include <iterator>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/math/tools/is_standalone.hpp>
|
||||
#ifndef BOOST_MATH_STANDALONE
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_MATH_NO_CXX17_IF_CONSTEXPR
|
||||
#error "The header <boost/math/norms.hpp> can only be used in C++17 and later."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace boost { namespace math{
|
||||
|
||||
template<class RandomAccessContainer>
|
||||
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<Real>)
|
||||
{
|
||||
if (x < m_v[0]) {
|
||||
return static_cast<double>(0);
|
||||
}
|
||||
if (x >= m_v[m_v.size()-1]) {
|
||||
return static_cast<double>(1);
|
||||
}
|
||||
auto it = std::upper_bound(m_v.begin(), m_v.end(), x);
|
||||
return static_cast<double>(std::distance(m_v.begin(), it))/static_cast<double>(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<Real>(std::distance(m_v.begin(), it))/static_cast<Real>(m_v.size());
|
||||
}
|
||||
}
|
||||
|
||||
RandomAccessContainer&& return_data() {
|
||||
return std::move(m_v);
|
||||
}
|
||||
|
||||
private:
|
||||
RandomAccessContainer m_v;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user