Compare commits

..
5 Commits
55540 changed files with 9471246 additions and 1966 deletions
-38
View File
@@ -1,38 +0,0 @@
#!/bin/bash
# Auto-cancel preceding workflows
# https://discuss.circleci.com/t/workaround-auto-cancel-redundant-builds-on-the-default-branch/39468
set -x
## Get the name of the workflow and the related pipeline number
curl --header "Circle-Token: $PERS_API_TOKEN_BOOST_5" --request GET "https://circleci.com/api/v2/workflow/${CIRCLE_WORKFLOW_ID}" -o current_workflow.json
WF_NAME=$(jq -r '.name' current_workflow.json)
CURRENT_PIPELINE_NUM=$(jq -r '.pipeline_number' current_workflow.json)
CURRENT_PIPELINE_CREATED=$(jq -r '.created_at' current_workflow.json)
TIME_THRESHOLD=$(date --utc +'%Y-%m-%dT%TZ' -d "${CURRENT_PIPELINE_CREATED} -10 minutes")
## Get the IDs of pipelines created by the current user on the same branch. (Only consider pipelines that have a pipeline number inferior to the current pipeline)
PIPE_IDS=$(curl --header "Circle-Token: $PERS_API_TOKEN_BOOST_5" --request GET "https://circleci.com/api/v2/project/gh/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME/pipeline?branch=$CIRCLE_BRANCH"|jq -r --argjson CURRENT_PIPELINE_NUM "$CURRENT_PIPELINE_NUM" --arg TIME_THRESHOLD "${TIME_THRESHOLD}" '.items[] | select(.state == "created") | select(.number < $CURRENT_PIPELINE_NUM) | select(.created_at > $TIME_THRESHOLD) | .id')
## Get the IDs of currently running/on_hold workflows that have the same name as the current workflow, in all previously created pipelines.
if [ ! -z "$PIPE_IDS" ]; then
for PIPE_ID in $PIPE_IDS
do
curl --header "Circle-Token: $PERS_API_TOKEN_BOOST_5" --request GET "https://circleci.com/api/v2/pipeline/${PIPE_ID}/workflow"|jq -r --arg WF_NAME "${WF_NAME}" '.items[]|select(.status == "on_hold" or .status == "running") | select(.name == $WF_NAME) | .id' >> WF_to_cancel.txt
done
fi
## Cancel any currently running/on_hold workflow with the same name
if [ -s WF_to_cancel.txt ]; then
echo "Cancelling the following workflow(s):"
cat WF_to_cancel.txt
while read WF_ID;
do
curl --header "Circle-Token: $PERS_API_TOKEN_BOOST_5" --request POST https://circleci.com/api/v2/workflow/$WF_ID/cancel
done < WF_to_cancel.txt
## Allowing some time to complete the cancellation
sleep 2
else
echo "Nothing to cancel"
fi
+2 -4
View File
@@ -1,13 +1,11 @@
version: 2.1
version: 2
jobs:
build:
resource_class: large
docker:
- image: cppalliance/boost_superproject_build:24.04-v4
- image: cppalliance/boost_superproject_build:20.04-v1
parallelism: 2
steps:
- checkout
- run: ./.circleci/autocancel.sh || true
- run: wget "https://raw.githubusercontent.com/boostorg/release-tools/master/ci_boost_common.py" -P ${HOME}
- run: wget "https://raw.githubusercontent.com/boostorg/release-tools/master/ci_boost_release.py" -P ${HOME}
- run: python3 ${HOME}/ci_boost_release.py checkout_post
+28 -323
View File
@@ -1,11 +1,8 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
tags:
- '**'
@@ -16,14 +13,15 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: ubuntu-24.04-arm
- os: macos-latest
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v3
with:
submodules: true
@@ -50,12 +48,13 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-latest
- os: windows-2019
- os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v3
with:
submodules: true
@@ -78,141 +77,20 @@ jobs:
cd status
../b2 -j3 quick
b2-check-installed-posix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Install Boost
run: |
./bootstrap.sh
./b2 -j3 --prefix=$HOME/.local install
- name: Test installed headers
run: |
g++ -I ~/.local/include -I /usr/include/python3.12 -std=c++20 -c tools/boost_install/test/headers/include.cpp
- name: Check installed files
run: |
file -E ~/.local/share/boost_predef/build.jam
file -E ~/.local/lib/cmake/BoostDetectToolset-*.cmake
file -E ~/.local/lib/cmake/Boost-*/BoostConfig.cmake
file -E ~/.local/lib/cmake/Boost-*/BoostConfigVersion.cmake
file -E ~/.local/lib/cmake/boost_headers-*/boost_headers-config.cmake
file -E ~/.local/lib/cmake/boost_headers-*/boost_headers-config-version.cmake
file -E ~/.local/lib/cmake/boost_system-*/boost_system-config.cmake
file -E ~/.local/lib/cmake/boost_system-*/boost_system-config-version.cmake
b2-cmake-tool-posix:
strategy:
fail-fast: false
matrix:
tool:
- boostdep
- inspect
- quickbook
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Install Boost
run: |
./bootstrap.sh
./b2 -j3 --prefix=$HOME/.local --with-filesystem --with-regex --with-program_options install
- name: Build tool with CMake
run: |
cmake -S tools/${{matrix.tool}} -B __build__ -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=~/.local
cmake --build __build__ --target install
b2-cmake-tool-windows:
strategy:
fail-fast: false
matrix:
tool:
- boostdep
- inspect
- quickbook
runs-on: windows-latest
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Install Boost
shell: cmd
run: |
cmd /c bootstrap
b2 -j3 --with-filesystem --with-regex --with-program_options install
- name: Build tool with CMake
run: |
cmake -S tools/${{matrix.tool}} -B __build__ -DBoost_ROOT=C:/Boost -DCMAKE_INSTALL_PREFIX=C:/usr/local
cmake --build __build__ --target install --config Release
b2-cmake-use-lib-posix:
strategy:
fail-fast: false
matrix:
lib:
- atomic
- container
- date_time
- filesystem
- headers
- log
- program_options
- python
- random
- regex
- serialization
- system
- test
- thread
- wave
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Install Boost --with-library
run: |
./bootstrap.sh
./b2 -j3 --prefix=$HOME/.local --with-${{matrix.lib}} install
- name: Use library from CMake
run: |
cmake -S tools/boost_install/test/${{matrix.lib}} -B __build__ -DCMAKE_INSTALL_PREFIX=~/.local
cmake --build __build__
export LD_LIBRARY_PATH=$HOME/.local/lib:$LD_LIBRARY_PATH
cmake --build __build__ --target check
cmake-install-posix:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: ubuntu-24.04-arm
- os: macos-latest
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
runs-on: ${{matrix.os}}
timeout-minutes: 20
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v3
with:
submodules: true
@@ -236,12 +114,13 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-latest
- os: windows-2019
- os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v3
with:
submodules: true
@@ -265,233 +144,59 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: ubuntu-20.04
- os: ubuntu-22.04
- os: macos-11
- os: macos-12
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v3
with:
submodules: true
- name: Configure Boost
run: |
mkdir __build__ && cd __build__
cmake -DBUILD_TESTING=ON -DBOOST_EXCLUDE_LIBRARIES="process;geometry" ..
cmake -DBUILD_TESTING=ON ..
- name: Build tests
run: |
cd __build__
cmake --build . -j 3 --target tests
- name: Run tests
run: |
cd __build__
ctest --output-on-failure --no-tests=error -j 3
cmake-test-posix-quick:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: ubuntu-24.04-arm
- os: macos-latest
runs-on: ${{matrix.os}}
timeout-minutes: 90
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Configure Boost
run: |
mkdir __build__ && cd __build__
cmake -DBUILD_TESTING=ON ..
- name: Build tests
run: |
cd __build__
cmake --build . -j 3 --target tests-quick
- name: Run tests
run: |
cd __build__
ctest --output-on-failure --no-tests=error -j 3 -R quick
cmake-test-windows-quick:
cmake-test-windows:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
- os: windows-2019
- os: windows-2022
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v3
with:
submodules: true
- name: Configure Boost
run: |
mkdir __build__ && cd __build__
cmake -DBUILD_TESTING=ON ..
cmake -DBUILD_TESTING=ON -DBOOST_EXCLUDE_LIBRARIES="convert;outcome" ..
- name: Build tests
run: |
cd __build__
cmake --build . -j 3 --target tests-quick
cmake --build . -j 3 --target tests
- name: Run tests
run: |
cd __build__
ctest --output-on-failure --no-tests=error -j 3 -R quick -C Debug
# setup windows-11-arm as it is new and does not have all requirements pre-installed.
setup-windows-arm64:
runs-on: windows-11-arm
outputs:
vcpkg-root: ${{ steps.set-vcpkg-root.outputs.vcpkg-root }}
steps:
- uses: actions/checkout@v6
- name: Install vcpkg
run: |
if (!(Test-Path C:\vcpkg)) {
git clone https://github.com/microsoft/vcpkg.git C:\vcpkg
C:\vcpkg\bootstrap-vcpkg.bat
}
else {
echo "vcpkg already installed"
}
- name: Restore vcpkg cache
id: cache-vcpkg
uses: actions/cache@v5
with:
path: |
C:\vcpkg\downloads
C:\vcpkg\installed
key: vcpkg-${{ runner.os }}-arm64
restore-keys: |
vcpkg-${{ runner.os }}-arm64
- name: Install OpenSSL via vcpkg (if not cached)
if: steps.cache-vcpkg.outputs.cache-hit != 'true'
run: |
C:\vcpkg\vcpkg install openssl:arm64-windows
- name: Set vcpkg-root output
id: set-vcpkg-root
shell: pwsh
run: |
echo "Writing vcpkg-root=C:\vcpkg to GITHUB_OUTPUT"
echo "vcpkg-root=C:\vcpkg" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
- name: Log step output
run: |
echo "Step output is: ${{ steps.set-vcpkg-root.outputs.vcpkg-root }}"
b2-windows-arm64:
needs: setup-windows-arm64
runs-on: windows-11-arm
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Setup Boost
shell: cmd
run: |
bootstrap
b2 -d0 headers
# There is no mpi support yet for Windows arm64. So built without mpi for now
# pch needs to be turned off, otherwise few components fail.
# It requires additional parameters to be pass for selecting correct asm files for boost:context
- name: Build Boost
run: ./b2 -j2 toolset=msvc architecture=arm address-model=64 abi=ms pch=off --without-mpi --without-graph_parallel stage
- name: Install Boost
run: ./b2 -j2 toolset=msvc architecture=arm address-model=64 abi=ms pch=off --without-mpi --without-graph_parallel install
- name: Test Boost
run: |
cd status
../b2 -j3 pch=off quick
# Win Arm64 CMake job
cmake-install-windows-arm64:
needs: setup-windows-arm64
runs-on: windows-11-arm
steps:
- uses: actions/checkout@v6
with:
submodules: true
- name: Restore vcpkg cache
uses: actions/cache@v5
with:
path: |
C:\vcpkg\downloads
C:\vcpkg\installed
key: vcpkg-${{ runner.os }}-arm64
# We are using vcpkg to install dependencies such as OpenSSL in windows-11-arm runner.
- name: Configure Boost
run: |
mkdir __build__ && cd __build__
$vcpkgRoot="${{ needs.setup-windows-arm64.outputs.vcpkg-root }}"
cmake -DBUILD_SHARED_LIBS=ON `
-DCMAKE_TOOLCHAIN_FILE="$vcpkgRoot\scripts\buildsystems\vcpkg.cmake" `
-DVCPKG_TARGET_TRIPLET=arm64-windows ..
- name: Build Boost
run: |
cd __build__
cmake --build . -j 3
- name: Install Boost
run: |
cd __build__
cmake --build . -j 3 --target install
# Win Arm64 CMake test job
cmake-test-windows-arm64-quick:
needs: setup-windows-arm64
runs-on: windows-11-arm
steps:
- uses: actions/checkout@v6
with:
submodules: true
# Restore cache
- uses: actions/cache@v5
with:
path: |
C:\vcpkg\downloads
C:\vcpkg\installed
key: vcpkg-${{ runner.os }}-arm64
# we are using vcpkg to install OpenSSL in windows-11-arm runner.
- name: Configure Boost
run: |
mkdir __build__; cd __build__
$vcpkgRoot="${{ needs.setup-windows-arm64.outputs.vcpkg-root }}"
cmake -DBUILD_TESTING=ON -DCMAKE_TOOLCHAIN_FILE="$vcpkgRoot\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=arm64-windows ..
- name: Build tests
run: |
cd __build__
cmake --build . -j2 --target tests-quick
- name: Run tests
run: |
cd __build__
ctest --output-on-failure --no-tests=error -j2 -R quick -C Debug
-134
View File
@@ -1,134 +0,0 @@
name: Commit Bot
# Instructions
#
# - One-time setup: create a personal access token with permissions. Then configure it here
# as secrets.CI_PAT. https://github.com/boostorg/boost/settings/secrets/actions
# The reason is explained in https://github.com/orgs/community/discussions/25702
# "If an action pushes code using the repository's GITHUB_TOKEN, a new workflow will not run"
#
# - Processing of either the 'master' or 'develop' branch may be stopped by creating the variables
# vars.block_master or vars.block_develop with the value "yes" (case-insensitive).
# https://github.com/boostorg/boost/settings/variables/actions
#
# To avoid infinite loops, don't trigger on "push"
on:
schedule:
- cron: "0,30 * * * *"
concurrency:
group: ${{format('commit-bot-{0}:{1}', github.repository, github.ref)}}
cancel-in-progress: true
jobs:
update-modules:
runs-on: ubuntu-latest
name: Commit Bot
if: github.repository == 'boostorg/boost'
steps:
- name: Check for module updates
id: branches
run: |
set -xe
branches=""
block_master="${{ vars.block_master }}"
block_develop="${{ vars.block_develop }}"
if [[ "${{ github.event_name }}" == "push" ]]; then
# The job doesn't run on "push" so this will not execute.
if [[ ! ${block_master,,} =~ yes && "${{ github.ref_name }}" == "master" ]]; then
branches="master"
elif [[ ! ${block_develop,,} =~ yes && "${{ github.ref_name }}" == "develop" ]]; then
branches="develop"
fi
else
# from a schedule:
if [[ ! ${block_master,,} =~ yes ]]; then
branches="master"
fi
if [[ ! ${block_develop,,} =~ yes ]]; then
branches="${branches} develop"
fi
fi
echo "branches=$branches" >> $GITHUB_OUTPUT
echo "branches is ${branches}"
- name: Checkout master repository
uses: actions/checkout@v4
if: contains(steps.branches.outputs.branches, 'master')
with:
ref: master
path: master
persist-credentials: false
- name: Checkout develop repository
uses: actions/checkout@v4
if: contains(steps.branches.outputs.branches, 'develop')
with:
ref: develop
path: develop
persist-credentials: false
- name: Check for module updates
run: |
branches="${{ steps.branches.outputs.branches }}"
# Set up Git
git config --global user.name "boost-commitbot"
git config --global user.email "boost-commitbot@example.com"
# Update each branch
for branch in $branches; do
cd $branch
module_paths=$(git config --file .gitmodules --get-regexp '^submodule\..*\.path$')
while IFS=' ' read -r key path; do
submodule_name=$(echo "$key" | awk -F '.' '{print $2}')
submodule_path=$(echo "$path")
url=$(git config --file .gitmodules --get-regexp "^submodule\.$submodule_name\.url$" | awk '{print $2}')
if [[ ! "$url" =~ ^https:// ]]; then
basicreponame=$(basename $url)
url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY_OWNER}/${basicreponame}
fi
hash=$(git ls-remote "$url" "refs/heads/$branch" | cut -f 1)
hash="${hash#"${hash%%[![:space:]]*}"}"
hash="${hash%"${hash##*[![:space:]]}"}"
commit_id="${hash:0:8}"
previous_hash=$(git ls-tree HEAD "$submodule_path" | awk '{print $3}')
previous_hash="${previous_hash#"${previous_hash%%[![:space:]]*}"}"
previous_hash="${previous_hash%"${previous_hash##*[![:space:]]}"}"
previous_commit_id="${previous_hash:0:8}"
if [ "$hash" == "$previous_hash" ]; then
echo "$submodule_name ($commit_id): OK"
else
echo "$submodule_name: $previous_commit_id -> $commit_id"
set -x
set +e
git submodule update --init "$submodule_path"
git submodule update --remote "$submodule_path"
git add "$submodule_path"
git commit -m "Update $submodule_name from $branch"
set -e
set +x
fi
done <<< "$module_paths"
cd ..
done
- name: Push changes from master
uses: ad-m/github-push-action@v0.8.0
if: contains(steps.branches.outputs.branches, 'master')
with:
# github_token: ${{ secrets.GITHUB_TOKEN }}
github_token: ${{ secrets.CI_PAT }}
branch: master
directory: master
- name: Push changes from develop
uses: ad-m/github-push-action@v0.8.0
if: contains(steps.branches.outputs.branches, 'develop')
with:
# github_token: ${{ secrets.GITHUB_TOKEN }}
github_token: ${{ secrets.CI_PAT }}
branch: develop
directory: develop
-152
View File
@@ -1,152 +0,0 @@
name: Release
on:
push:
tags:
- boost-*
permissions:
contents: write
jobs:
release-posix-cmake:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
path: ${{ github.ref_name }}
submodules: true
- name: Cleanup
shell: bash
run: |
find ${{ github.ref_name }} -name ".git" -prune -exec rm -rf {} +
- name: Create archives
run: |
tar -czf ${{ github.ref_name }}-cmake.tar.gz ${{ github.ref_name }}
sha256sum ${{ github.ref_name }}-cmake.tar.gz > ${{ github.ref_name }}-cmake.tar.gz.txt
tar -cJf ${{ github.ref_name }}-cmake.tar.xz ${{ github.ref_name }}
sha256sum ${{ github.ref_name }}-cmake.tar.xz > ${{ github.ref_name }}-cmake.tar.xz.txt
- uses: softprops/action-gh-release@v3
with:
files: |
${{ github.ref_name }}-cmake.tar.gz
${{ github.ref_name }}-cmake.tar.gz.txt
${{ github.ref_name }}-cmake.tar.xz
${{ github.ref_name }}-cmake.tar.xz.txt
release-windows-cmake:
runs-on: windows-latest
needs: release-posix-cmake
steps:
- uses: actions/checkout@v6
with:
path: ${{ github.ref_name }}
submodules: true
- name: Cleanup
shell: bash
run: |
find ${{ github.ref_name }} -name ".git" -prune -exec rm -rf {} +
- name: Create archives
shell: cmd
run: |
7z a ${{ github.ref_name }}-cmake.zip ${{ github.ref_name }}
sha256sum ${{ github.ref_name }}-cmake.zip > ${{ github.ref_name }}-cmake.zip.txt
7z a ${{ github.ref_name }}-cmake.7z ${{ github.ref_name }}
sha256sum ${{ github.ref_name }}-cmake.7z > ${{ github.ref_name }}-cmake.7z.txt
- uses: softprops/action-gh-release@v3
with:
files: |
${{ github.ref_name }}-cmake.zip
${{ github.ref_name }}-cmake.zip.txt
${{ github.ref_name }}-cmake.7z
${{ github.ref_name }}-cmake.7z.txt
release-posix-b2-nodocs:
runs-on: ubuntu-latest
needs: release-windows-cmake
steps:
- uses: actions/checkout@v6
with:
path: ${{ github.ref_name }}
submodules: true
- name: Cleanup
shell: bash
run: |
find ${{ github.ref_name }} -name ".git" -prune -exec rm -rf {} +
- name: Move headers, remove docs
shell: bash
run: |
cd ${{ github.ref_name }}
cp -r libs/*/include/boost libs/numeric/*/include/boost .
rm -rf libs/*/include libs/numeric/*/include
rm -rf libs/*/doc libs/numeric/*/doc
rm -f CMakeLists.txt
- name: Create archives
run: |
tar -czf ${{ github.ref_name }}-b2-nodocs.tar.gz ${{ github.ref_name }}
sha256sum ${{ github.ref_name }}-b2-nodocs.tar.gz > ${{ github.ref_name }}-b2-nodocs.tar.gz.txt
tar -cJf ${{ github.ref_name }}-b2-nodocs.tar.xz ${{ github.ref_name }}
sha256sum ${{ github.ref_name }}-b2-nodocs.tar.xz > ${{ github.ref_name }}-b2-nodocs.tar.xz.txt
- uses: softprops/action-gh-release@v3
with:
files: |
${{ github.ref_name }}-b2-nodocs.tar.gz
${{ github.ref_name }}-b2-nodocs.tar.gz.txt
${{ github.ref_name }}-b2-nodocs.tar.xz
${{ github.ref_name }}-b2-nodocs.tar.xz.txt
release-windows-b2-nodocs:
runs-on: windows-latest
needs: release-posix-b2-nodocs
steps:
- uses: actions/checkout@v6
with:
path: ${{ github.ref_name }}
submodules: true
- name: Cleanup
shell: bash
run: |
find ${{ github.ref_name }} -name ".git" -prune -exec rm -rf {} +
- name: Move headers, remove docs
shell: bash
run: |
cd ${{ github.ref_name }}
cp -r libs/*/include/boost libs/numeric/*/include/boost .
rm -rf libs/*/include libs/numeric/*/include
rm -rf libs/*/doc libs/numeric/*/doc
rm -f CMakeLists.txt
- name: Create archives
shell: cmd
run: |
7z a ${{ github.ref_name }}-b2-nodocs.zip ${{ github.ref_name }}
sha256sum ${{ github.ref_name }}-b2-nodocs.zip > ${{ github.ref_name }}-b2-nodocs.zip.txt
7z a ${{ github.ref_name }}-b2-nodocs.7z ${{ github.ref_name }}
sha256sum ${{ github.ref_name }}-b2-nodocs.7z > ${{ github.ref_name }}-b2-nodocs.7z.txt
- uses: softprops/action-gh-release@v3
with:
files: |
${{ github.ref_name }}-b2-nodocs.zip
${{ github.ref_name }}-b2-nodocs.zip.txt
${{ github.ref_name }}-b2-nodocs.7z
${{ github.ref_name }}-b2-nodocs.7z.txt
+60
View File
@@ -0,0 +1,60 @@
name: Release
on:
push:
tags:
- boost-*
jobs:
release-posix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
path: ${{ github.ref_name }}
submodules: true
- name: Cleanup
shell: bash
run: |
find ${{ github.ref_name }} -name ".git" -prune -exec rm -rf {} +
- name: Create archives
run: |
tar -czf ${{ github.ref_name }}.tar.gz ${{ github.ref_name }}
tar -cJf ${{ github.ref_name }}.tar.xz ${{ github.ref_name }}
- uses: softprops/action-gh-release@v1
with:
files: |
${{ github.ref_name }}.tar.gz
${{ github.ref_name }}.tar.xz
release-windows:
runs-on: windows-latest
needs: release-posix
steps:
- uses: actions/checkout@v3
with:
path: ${{ github.ref_name }}
submodules: true
- name: Cleanup
shell: bash
run: |
find ${{ github.ref_name }} -name ".git" -prune -exec rm -rf {} +
- name: Create archives
shell: cmd
run: |
7z a ${{ github.ref_name }}.zip ${{ github.ref_name }}
7z a ${{ github.ref_name }}.7z ${{ github.ref_name }}
- uses: softprops/action-gh-release@v1
with:
files: |
${{ github.ref_name }}.zip
${{ github.ref_name }}.7z
-860
View File
@@ -1,860 +0,0 @@
[submodule "system"]
path = libs/system
url = ../system.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "multi_array"]
path = libs/multi_array
url = ../multi_array.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "math"]
path = libs/math
url = ../math.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "smart_ptr"]
path = libs/smart_ptr
url = ../smart_ptr.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "parameter"]
path = libs/parameter
url = ../parameter.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "algorithm"]
path = libs/algorithm
url = ../algorithm.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "any"]
path = libs/any
url = ../any.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "concept_check"]
path = libs/concept_check
url = ../concept_check.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "python"]
path = libs/python
url = ../python.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "tti"]
path = libs/tti
url = ../tti.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "functional"]
path = libs/functional
url = ../functional.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "config"]
path = libs/config
url = ../config.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "log"]
path = libs/log
url = ../log.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "interprocess"]
path = libs/interprocess
url = ../interprocess.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "exception"]
path = libs/exception
url = ../exception.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "foreach"]
path = libs/foreach
url = ../foreach.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "spirit"]
path = libs/spirit
url = ../spirit.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "io"]
path = libs/io
url = ../io.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "units"]
path = libs/units
url = ../units.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "preprocessor"]
path = libs/preprocessor
url = ../preprocessor.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "format"]
path = libs/format
url = ../format.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "xpressive"]
path = libs/xpressive
url = ../xpressive.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "integer"]
path = libs/integer
url = ../integer.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "thread"]
path = libs/thread
url = ../thread.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "tokenizer"]
path = libs/tokenizer
url = ../tokenizer.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "timer"]
path = libs/timer
url = ../timer.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "inspect"]
path = tools/inspect
url = ../inspect.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "boostbook"]
path = tools/boostbook
url = ../boostbook.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "regex"]
path = libs/regex
url = ../regex.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "crc"]
path = libs/crc
url = ../crc.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "random"]
path = libs/random
url = ../random.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "serialization"]
path = libs/serialization
url = ../serialization.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "test"]
path = libs/test
url = ../test.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "date_time"]
path = libs/date_time
url = ../date_time.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "logic"]
path = libs/logic
url = ../logic.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "graph"]
path = libs/graph
url = ../graph.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "numeric_conversion"]
path = libs/numeric/conversion
url = ../numeric_conversion.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "lambda"]
path = libs/lambda
url = ../lambda.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "mpl"]
path = libs/mpl
url = ../mpl.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "typeof"]
path = libs/typeof
url = ../typeof.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "tuple"]
path = libs/tuple
url = ../tuple.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "utility"]
path = libs/utility
url = ../utility.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "dynamic_bitset"]
path = libs/dynamic_bitset
url = ../dynamic_bitset.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "assign"]
path = libs/assign
url = ../assign.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "filesystem"]
path = libs/filesystem
url = ../filesystem.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "function"]
path = libs/function
url = ../function.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "conversion"]
path = libs/conversion
url = ../conversion.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "optional"]
path = libs/optional
url = ../optional.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "property_tree"]
path = libs/property_tree
url = ../property_tree.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "bimap"]
path = libs/bimap
url = ../bimap.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "variant"]
path = libs/variant
url = ../variant.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "array"]
path = libs/array
url = ../array.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "iostreams"]
path = libs/iostreams
url = ../iostreams.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "multi_index"]
path = libs/multi_index
url = ../multi_index.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "bcp"]
path = tools/bcp
url = ../bcp.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "ptr_container"]
path = libs/ptr_container
url = ../ptr_container.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "statechart"]
path = libs/statechart
url = ../statechart.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "static_assert"]
path = libs/static_assert
url = ../static_assert.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "range"]
path = libs/range
url = ../range.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "rational"]
path = libs/rational
url = ../rational.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "iterator"]
path = libs/iterator
url = ../iterator.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "build"]
path = tools/build
url = ../build.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "quickbook"]
path = tools/quickbook
url = ../quickbook.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "graph_parallel"]
path = libs/graph_parallel
url = ../graph_parallel.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "property_map"]
path = libs/property_map
url = ../property_map.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "program_options"]
path = libs/program_options
url = ../program_options.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "detail"]
path = libs/detail
url = ../detail.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "interval"]
path = libs/numeric/interval
url = ../interval.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "ublas"]
path = libs/numeric/ublas
url = ../ublas.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "wave"]
path = libs/wave
url = ../wave.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "type_traits"]
path = libs/type_traits
url = ../type_traits.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "bind"]
path = libs/bind
url = ../bind.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "pool"]
path = libs/pool
url = ../pool.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "proto"]
path = libs/proto
url = ../proto.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "fusion"]
path = libs/fusion
url = ../fusion.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "function_types"]
path = libs/function_types
url = ../function_types.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "gil"]
path = libs/gil
url = ../gil.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "intrusive"]
path = libs/intrusive
url = ../intrusive.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "asio"]
path = libs/asio
url = ../asio.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "uuid"]
path = libs/uuid
url = ../uuid.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "litre"]
path = tools/litre
url = ../litre.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "circular_buffer"]
path = libs/circular_buffer
url = ../circular_buffer.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "mpi"]
path = libs/mpi
url = ../mpi.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "unordered"]
path = libs/unordered
url = ../unordered.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "signals2"]
path = libs/signals2
url = ../signals2.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "accumulators"]
path = libs/accumulators
url = ../accumulators.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "atomic"]
path = libs/atomic
url = ../atomic.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "scope_exit"]
path = libs/scope_exit
url = ../scope_exit.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "flyweight"]
path = libs/flyweight
url = ../flyweight.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "icl"]
path = libs/icl
url = ../icl.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "predef"]
path = libs/predef
url = ../predef.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "chrono"]
path = libs/chrono
url = ../chrono.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "polygon"]
path = libs/polygon
url = ../polygon.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "msm"]
path = libs/msm
url = ../msm.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "heap"]
path = libs/heap
url = ../heap.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "coroutine"]
path = libs/coroutine
url = ../coroutine.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "coroutine2"]
path = libs/coroutine2
url = ../coroutine2.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "ratio"]
path = libs/ratio
url = ../ratio.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "odeint"]
path = libs/numeric/odeint
url = ../odeint.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "geometry"]
path = libs/geometry
url = ../geometry.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "phoenix"]
path = libs/phoenix
url = ../phoenix.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "move"]
path = libs/move
url = ../move.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "locale"]
path = libs/locale
url = ../locale.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "auto_index"]
path = tools/auto_index
url = ../auto_index.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "container"]
path = libs/container
url = ../container.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "local_function"]
path = libs/local_function
url = ../local_function.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "context"]
path = libs/context
url = ../context.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "type_erasure"]
path = libs/type_erasure
url = ../type_erasure.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "multiprecision"]
path = libs/multiprecision
url = ../multiprecision.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "lockfree"]
path = libs/lockfree
url = ../lockfree.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "assert"]
path = libs/assert
url = ../assert.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "align"]
path = libs/align
url = ../align.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "type_index"]
path = libs/type_index
url = ../type_index.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "core"]
path = libs/core
url = ../core.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "throw_exception"]
path = libs/throw_exception
url = ../throw_exception.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "winapi"]
path = libs/winapi
url = ../winapi.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "boostdep"]
path = tools/boostdep
url = ../boostdep.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "lexical_cast"]
path = libs/lexical_cast
url = ../lexical_cast.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "sort"]
path = libs/sort
url = ../sort.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "convert"]
path = libs/convert
url = ../convert.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "endian"]
path = libs/endian
url = ../endian.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "vmd"]
path = libs/vmd
url = ../vmd.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "dll"]
path = libs/dll
url = ../dll.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "compute"]
path = libs/compute
url = ../compute.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "hana"]
path = libs/hana
url = ../hana.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "metaparse"]
path = libs/metaparse
url = ../metaparse.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "qvm"]
path = libs/qvm
url = ../qvm.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "fiber"]
path = libs/fiber
url = ../fiber.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "process"]
path = libs/process
url = ../process.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "stacktrace"]
path = libs/stacktrace
url = ../stacktrace.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "poly_collection"]
path = libs/poly_collection
url = ../poly_collection.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "beast"]
path = libs/beast
url = ../beast.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "mp11"]
path = libs/mp11
url = ../mp11.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "callable_traits"]
path = libs/callable_traits
url = ../callable_traits.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "contract"]
path = libs/contract
url = ../contract.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "check_build"]
path = tools/check_build
url = ../check_build.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "container_hash"]
path = libs/container_hash
url = ../container_hash.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "hof"]
path = libs/hof
url = ../hof.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "yap"]
path = libs/yap
url = ../yap.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "safe_numerics"]
path = libs/safe_numerics
url = ../safe_numerics.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "parameter_python"]
path = libs/parameter_python
url = ../parameter_python.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "headers"]
path = libs/headers
url = ../headers.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "boost_install"]
path = tools/boost_install
url = ../boost_install.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "outcome"]
path = libs/outcome
url = ../outcome.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "histogram"]
path = libs/histogram
url = ../histogram.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "variant2"]
path = libs/variant2
url = ../variant2.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "nowide"]
path = libs/nowide
url = ../nowide.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "docca"]
path = tools/docca
url = ../docca.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "cmake"]
path = tools/cmake
url = ../cmake.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "static_string"]
path = libs/static_string
url = ../static_string.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "stl_interfaces"]
path = libs/stl_interfaces
url = ../stl_interfaces.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "more"]
path = more
url = ../more.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "leaf"]
path = libs/leaf
url = ../leaf.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "json"]
path = libs/json
url = ../json.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "pfr"]
path = libs/pfr
url = ../pfr.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "describe"]
path = libs/describe
url = ../describe.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "lambda2"]
path = libs/lambda2
url = ../lambda2.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "property_map_parallel"]
path = libs/property_map_parallel
url = ../property_map_parallel.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "url"]
path = libs/url
url = ../url.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "mysql"]
path = libs/mysql
url = ../mysql.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "compat"]
path = libs/compat
url = ../compat.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "redis"]
path = libs/redis
url = ../redis.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "cobalt"]
path = libs/cobalt
url = ../cobalt.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "charconv"]
path = libs/charconv
url = ../charconv.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "scope"]
path = libs/scope
url = ../scope.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "boostlook"]
path = tools/boostlook
url = ../boostlook.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "parser"]
path = libs/parser
url = ../parser.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "mqtt5"]
path = libs/mqtt5
url = ../mqtt5.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "hash2"]
path = libs/hash2
url = ../hash2.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "bloom"]
path = libs/bloom
url = ../bloom.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "openmethod"]
path = libs/openmethod
url = ../openmethod.git
fetchRecurseSubmodules = on-demand
branch = .
[submodule "decimal"]
path = libs/decimal
url = ../decimal.git
fetchRecurseSubmodules = on-demand
branch = .
+2 -2
View File
@@ -2,7 +2,7 @@
# 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
cmake_minimum_required(VERSION 3.8...3.16)
cmake_minimum_required(VERSION 3.5...3.16)
# The default build type must be set before project()
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
@@ -10,7 +10,7 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND NOT CMAKE_BUILD_TYPE A
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
project(Boost VERSION 1.92.0 LANGUAGES CXX)
project(Boost VERSION 1.85.0 LANGUAGES CXX)
set(BOOST_SUPERPROJECT_VERSION ${PROJECT_VERSION})
set(BOOST_SUPERPROJECT_SOURCE_DIR ${PROJECT_SOURCE_DIR})
+32 -194
View File
@@ -1,6 +1,6 @@
# Copyright Vladimir Prus 2002-2006.
# Copyright Dave Abrahams 2005-2006.
# Copyright René Ferdinand Rivera Morell 2005-2024.
# Copyright Rene Rivera 2005-2007.
# Copyright Douglas Gregor 2005.
#
# Distributed under the Boost Software License, Version 1.0.
@@ -28,13 +28,7 @@
# --libdir=<LIBDIR> Install library files here.
# Default: <EPREFIX>/lib
#
# --bindir=<BINDIR> Install binary files here.
# Default: <EPREFIX>/bin
#
# --dlldir=<DLLDIR> Install Windows .dll files here.
# Default: <BINDIR>
#
# --includedir=<INCDIR> Install header files here.
# --includedir=<HDRDIR> Install header files here.
# Default: <PREFIX>/include
#
# --cmakedir=<CMAKEDIR> Install CMake configuration files here.
@@ -42,20 +36,11 @@
#
# --no-cmake-config Do not install CMake configuration files.
#
# --datadir=<DATADIR> Install data files here.
# Default: <PREFIX>/share
#
# stage Build and install only compiled library files to the
# ===== stage directory.
#
# --stagedir=<STAGEDIR> Stage library files here
# Default: <BOOST_ROOT>/stage
#
# --stage-libdir=<STAGELIBDIR> Stage library files here
# Default: <STAGEDIR>/lib
#
# --stage-includedir=<STAGEINCDIR> Stage header files here
# Default: <BOOST_ROOT>
# --stagedir=<STAGEDIR> Install library files here
# Default: ./stage
#
# Other Options:
#
@@ -137,8 +122,6 @@
# runtime.
#
require-b2 5.1.0 ;
# TODO:
# - handle boost version
# - handle python options such as pydebug
@@ -158,17 +141,15 @@ import property-set ;
import threadapi-feature ;
import option ;
import property ;
import project ;
# Backslash because of `bcp --namespace`
import tools/boost\_install/boost-install ;
path-constant BOOST_ROOT : . ;
constant BOOST_VERSION : 1.92.0 ;
constant BOOST_VERSION : 1.85.0 ;
constant BOOST_JAMROOT_MODULE : $(__name__) ;
# Allow subprojects to simply `import config : requires ;` to get access to the requires rule
import-search $(BOOST_ROOT)/libs/config/checks ;
import-search $(BOOST_ROOT)/libs/predef/tools/check ;
modules.poke : BOOST_BUILD_PATH : $(BOOST_ROOT)/libs/config/checks [ modules.peek : BOOST_BUILD_PATH ] ;
boostcpp.set-version $(BOOST_VERSION) ;
@@ -188,10 +169,11 @@ if $(all-headers)
constant BOOST_MODULARLAYOUT : $(all-headers) ;
}
project /boost
project boost
: requirements <include>.
[ boostcpp.platform ]
[ boostcpp.architecture ]
[ boostcpp.address-model ]
# Disable auto-linking for all targets here, primarily because it caused
# troubles with V2.
@@ -213,13 +195,6 @@ project /boost
: build-dir bin.v2
;
# General, top-level, modular project searching. Also include tools in the
# project search.
project-search /boost : libs tools ;
# Temporary custom project searching to account for special library paths.
project-search /boost : libs/numeric ;
project-search /boost/numeric_conversion : libs/numeric/conversion ;
# This rule is called by Boost.Build to determine the name of target. We use it
# to encode the build variant, compiler name and boost version in the target
# name.
@@ -267,80 +242,40 @@ rule clang-darwin-cxxstd-11 ( properties * )
return $(result) ;
}
# All libraries.
local all-libraries
= [ MATCH .*libs/(.*)/meta/libraries.json : [ glob libs/*/meta/libraries.json ] ] ;
all-libraries = [ MATCH .*libs/(.*)/build/.* : [ glob libs/*/build/Jamfile.v2 ]
[ glob libs/*/build/Jamfile ] ] ;
# Find all the libraries that have something to build (the old way).
local all-libraries-to-build
= [ MATCH .*libs/(.*)/build/.* : [ glob libs/*/build/Jamfile.v2 ]
[ glob libs/*/build/Jamfile ] ] ;
all-libraries-to-build = [ sequence.unique $(all-libraries-to-build) ] ;
all-libraries = [ sequence.unique $(all-libraries) ] ;
# The function_types library has a Jamfile, but it's used for maintenance
# purposes, there's no library to build and install.
all-libraries-to-build = [ set.difference $(all-libraries-to-build) : function_types ] ;
# Find all the libraries that have a library-root build declaration (modular way).
local all-libraries-modular-build
= [ MATCH .*libs/(.*)/build.jam : [ glob libs/*/build.jam ] ] ;
# Modular and not are mutually exclusive as they have different lib targets.
local all-libraries-old-build = [ set.difference $(all-libraries-to-build) : $(all-libraries-modular-build) ] ;
# The header only libraries that are not of the new modular form. For which we
# will create synthetic projects and targets to simulate the new modular form.
local all-libraries-to-declare
= [ set.difference $(all-libraries)
: $(all-libraries-modular-build) $(all-libraries-old-build) ] ;
if ! [ glob libs/numeric/conversion/build.jam ]
{
all-libraries-to-declare += numeric_conversion ;
}
if ! [ glob libs/numeric/interval/build.jam ]
{
all-libraries-to-declare += interval ;
}
if ! [ glob libs/numeric/odeint/build.jam ]
{
all-libraries-to-declare += odeint ;
}
if ! [ glob libs/numeric/ublas/build.jam ]
{
all-libraries-to-declare += ublas ;
}
all-libraries-to-declare = [ SORT $(all-libraries-to-declare) ] ;
# ECHO "INFO: Build Libraries:" [ SORT $(all-libraries-old-build) ] ;
# ECHO "INFO: Modular Libraries:" [ SORT $(all-libraries-modular-build) ] ;
# ECHO "INFO: Declared Libraries:" [ SORT $(all-libraries-to-declare) ] ;
# EXIT : 0 ;
all-libraries = [ set.difference $(all-libraries) : function_types ] ;
# Setup convenient aliases for all libraries.
local rule explicit-alias ( id : targets + )
{
alias $(id) : $(targets) ;
explicit $(id) ;
}
# First, the complicated libraries: where the target name in Jamfile is
# different from its directory name.
explicit
[ alias prg_exec_monitor : libs/test/build//boost_prg_exec_monitor ]
[ alias test_exec_monitor : libs/test/build//boost_test_exec_monitor ]
[ alias unit_test_framework : libs/test/build//boost_unit_test_framework ]
[ alias serialization : libs/serialization/build//boost_serialization ]
[ alias wserialization : libs/serialization/build//boost_wserialization ]
;
for local l in $(all-libraries-old-build)
explicit-alias prg_exec_monitor : libs/test/build//boost_prg_exec_monitor ;
explicit-alias test_exec_monitor : libs/test/build//boost_test_exec_monitor ;
explicit-alias unit_test_framework : libs/test/build//boost_unit_test_framework ;
explicit-alias serialization : libs/serialization/build//boost_serialization ;
explicit-alias wserialization : libs/serialization/build//boost_wserialization ;
for local l in $(all-libraries)
{
if ! $(l) in test graph serialization headers
{
explicit [ alias $(l) : libs/$(l)/build//boost_$(l) ] ;
}
}
for local l in $(all-libraries-modular-build)
{
if ! $(l) in test graph serialization headers
{
explicit [ alias $(l) : /boost/$(l)//boost_$(l) ] ;
explicit-alias $(l) : libs/$(l)/build//boost_$(l) ;
}
}
# Log has an additional target
explicit-alias log_setup : libs/log/build//boost_log_setup ;
rule do-nothing { }
rule generate-alias ( project name : property-set : sources * )
@@ -359,7 +294,7 @@ generate headers : $(all-headers)-headers : <generating-rule>@generate-alias <ac
explicit headers ;
# Make project ids of all libraries known.
for local l in $(all-libraries-old-build)
for local l in $(all-libraries)
{
use-project /boost/$(l) : libs/$(l)/build ;
}
@@ -371,7 +306,7 @@ if [ path.exists $(BOOST_ROOT)/tools/inspect/build ]
if [ path.exists $(BOOST_ROOT)/libs/wave/tool/build ]
{
use-project /boost/libs/wave/tool : $(BOOST_ROOT)/libs/wave/tool/build ;
use-project /boost/libs/wave/tool : libs/wave/tool/build ;
}
# Make the boost-install rule visible in subprojects
@@ -406,101 +341,4 @@ rule boost-lib ( name : sources * : requirements * : default-build * : usage-req
# Declare special top-level targets that build and install the desired variants
# of the libraries.
local former-libraries-to-build ;
if system in $(all-libraries)
{
former-libraries-to-build += system ;
}
boostcpp.declare-targets $(all-libraries-modular-build) :
[ SORT $(all-libraries-to-build) $(former-libraries-to-build) ] ;
# Declare a Boost library and run related declaration rules. This should be
# called from the libroot/build.jam to define the components of a Boost lib.
# The first arg is the base ID of the library. Each subsequence arg is a
# Boost (boost-x) declaration rule to call with arguments.
#
# For example:
#
# call-if : boost-library serialization
# : install boost_serialization boost_wserialization ;
#
rule boost-library ( id ? : options * : * )
{
# ECHO "INFO: Declare Boost library:" $(id) ;
local called-boost-install ;
for n in 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
{
local option = $($(n)) ;
if $(option)
{
call-if : boost-$(option[1]) $(option[2-]) ;
if $(option[1]) = install
{
called-boost-install = true ;
}
}
}
if ! $(called-boost-install)
{
# If the library didn't indicate an install build target it's likely
# header only. We should declare empty install targets to allow for
# generic handling.
boost-install.boost-install ;
}
}
# Declare projects and targets for all placeholder, header only, not yet
# modular libraries.
#
# NOTE: This has to be after the boost-* rule definitions to ensure that those
# are available for import into the new projects.
local location = [ project.attribute $(__name__) location ] ;
for local lib in $(all-libraries-to-declare)
{
local lib-path
= [ path.join $(location) libs $(lib) ] ;
if $(lib) = numeric_conversion
{
lib-path = [ path.join $(location) libs/numeric/conversion ] ;
}
else if $(lib) in interval odeint ublas
{
lib-path = [ path.join $(location) libs/numeric/$(lib) ] ;
}
local lib-module
= [ project.load $(lib-path) : synthesize ] ;
modules.poke $(lib-module) : BOOST_LIB_PROJECT : /boost/$(lib) ;
modules.poke $(lib-module) : BOOST_LIB_TARGET : boost_$(lib) ;
project.push-current [ project.target $(lib-module) ] ;
module $(lib-module)
{
project $(BOOST_LIB_PROJECT)
: requirements
<implicit-dependency>/boost//headers
;
alias $(BOOST_LIB_TARGET) ;
}
project.pop-current ;
}
# Backslash because of `bcp --namespace`
if ! [ project.search /boost/tools/boost\_install ]
{
use-project /boost/tools/boost\_install : tools/boost\_install ;
}
# Ensure "modular" libraries' projects are loaded before build request is
# calculated. This is necessary for subprojects that define custom features
# to be set by users on command line.
# This part should stay at the bottom of the file, because subprojects may rely
# on rules or constants from it.
for local l in $(all-libraries-modular-build)
{
# project.find returns the module for the project, which ensures that the
# project is loaded. The convoluted way the rule is invoked is due to the
# fact that project.find can only be called from a project target instance.
modules.call-in [ project.target $(__name__) ]
: project.find /boost/$(l)
: $(location) ;
}
boostcpp.declare-targets $(all-libraries) ;
+53 -79
View File
@@ -185,7 +185,7 @@ else
rule tag ( name : type ? : property-set )
{
if $(type:E=x) in STATIC_LIB SHARED_LIB IMPORT_LIB
if $(type) in STATIC_LIB SHARED_LIB IMPORT_LIB
{
local args = $(.format-name-args) ;
if $(layout) = versioned
@@ -263,27 +263,11 @@ rule python-tag ( name : type ? : property-set )
rule declare_install_and_stage_proper_targets ( libraries * )
{
local p = [ project.current ] ;
local install-targets ;
local stage-targets ;
for local library in $(libraries)
{
local mp = [ project.search /boost/$(library) ] ;
if $(mp)
{
install-targets += /boost/$(library)//install ;
stage-targets += /boost/$(library)//stage ;
}
else
{
install-targets += libs/$(library)/build//install ;
stage-targets += libs/$(library)/build//stage ;
}
}
alias install-proper : $(install-targets) ;
alias install-proper : libs/$(libraries)/build//install ;
$(p).mark-target-as-explicit install-proper ;
alias stage-proper : $(stage-targets) ;
alias stage-proper : libs/$(libraries)/build//stage ;
$(p).mark-target-as-explicit stage-proper ;
}
@@ -589,28 +573,25 @@ rule libraries-to-install ( existing-libs * )
}
}
rule declare-targets ( modular-libraries * : compiled-libraries * )
rule declare-targets ( all-libraries * )
{
configure.register-components $(compiled-libraries) ;
configure.register-components $(all-libraries) ;
# Select the libraries to install.
local filtered = [ libraries-to-install $(compiled-libraries) ] ;
configure.components-building $(filtered) ;
libraries = [ libraries-to-install $(all-libraries) ] ;
configure.components-building $(libraries) ;
if [ option.get "show-libraries" : : true ]
{
ECHO The following libraries require building\: ;
for local l in $(filtered)
for local l in $(libraries)
{
echo " - $(l)" ;
ECHO " - $(l)" ;
}
EXIT ;
}
local header-only-modular = [ set.difference $(modular-libraries) :
$(compiled-libraries) ] ;
declare_top_level_targets $(filtered) $(header-only-modular) ;
declare_top_level_targets $(libraries) ;
}
# Returns the properties identifying the toolset. We'll use them
@@ -625,38 +606,49 @@ rule toolset-properties ( properties * )
return [ property.select <target-os> <toolset> $(toolset-version-property) : $(properties) ] ;
}
.deducible-architectures = arm loongarch mips power riscv s390x sparc x86 combined ;
feature.feature x-deduced-platform
: $(.deducible-architectures)_32 $(.deducible-architectures)_64
: composite implicit optional propagated ;
for a in $(.deducible-architectures)
{
feature.compose <x-deduced-platform>$(a)_32 : <architecture>$(a) <address-model>32 ;
feature.compose <x-deduced-platform>$(a)_64 : <architecture>$(a) <address-model>64 ;
}
feature.feature deduced-address-model : 32 64 : propagated optional composite hidden ;
feature.compose <deduced-address-model>32 : <address-model>32 ;
feature.compose <deduced-address-model>64 : <address-model>64 ;
rule deduce-architecture ( properties * )
rule deduce-address-model ( properties * )
{
local deduced-pl = [ property.select <x-deduced-platform> : $(properties) ] ;
if $(deduced-pl)
{
return $(deduced-pl) ;
}
local result ;
local filtered = [ toolset-properties $(properties) ] ;
local names = 32 64 ;
local idx = [ configure.find-builds "default address-model" : $(filtered)
: /boost/architecture//32 "32-bit"
: /boost/architecture//64 "64-bit" ] ;
local deduced-am = $(names[$(idx)]) ;
if ! $(deduced-am)
{
return ;
}
result = $(names[$(idx)]) ;
names = $(.deducible-architectures) ;
idx = [ configure.find-builds "default architecture" : $(filtered)
if $(result)
{
# Normally, returning composite feature here is equivalent to forcing
# constituent properties as well. But we only want to indicate toolset
# deduced default, so also pick whatever address-model is explicitly
# specified, if any.
result = <deduced-address-model>$(result) [ property.select <address-model> : $(properties) ] ;
}
return $(result) ;
}
rule address-model ( )
{
return <conditional>@boostcpp.deduce-address-model ;
}
local deducable-architectures = arm loongarch mips power riscv s390x sparc x86 combined ;
feature.feature deduced-architecture : $(deducable-architectures) : propagated optional composite hidden ;
for a in $(deducable-architectures)
{
feature.compose <deduced-architecture>$(a) : <architecture>$(a) ;
}
rule deduce-architecture ( properties * )
{
local result ;
local filtered = [ toolset-properties $(properties) ] ;
local names = arm loongarch mips power riscv s390x sparc x86 combined ;
local idx = [ configure.find-builds "default architecture" : $(filtered)
: /boost/architecture//arm
: /boost/architecture//loongarch
: /boost/architecture//mips
@@ -666,35 +658,17 @@ rule deduce-architecture ( properties * )
: /boost/architecture//sparc
: /boost/architecture//x86
: /boost/architecture//combined ] ;
local deduced-arch = $(names[$(idx)]) ;
if ! $(deduced-arch)
result = $(names[$(idx)]) ;
if $(result)
{
return ;
# See comment in deduce-address-model.
result = <deduced-architecture>$(result) [ property.select <architecture> : $(properties) ] ;
}
local requested-am = [ property.select <address-model> : $(properties) ] ;
requested-am ?= <address-model>$(deduced-am) ;
local requested-arch = [ property.select <architecture> : $(properties) ] ;
requested-arch ?= <architecture>$(deduced-arch) ;
deduced-pl = $(requested-arch:G=<x-deduced-platform>)_$(requested-am:G=) ;
if ! $(deduced-pl:G=) in [ feature.values <x-deduced-platform> ]
{
deduced-pl = ;
}
return $(deduced-pl) ;
return $(result) ;
}
rule deduce-address-model ( properties * )
rule architecture ( )
{
# this rule is a noop and exists for legacy reasons
}
rule platform ( )
{
return <conditional>@boostcpp.deduce-architecture
<conditional>@boostcpp.deduce-address-model ;
return <conditional>@boostcpp.deduce-architecture ;
}
-1
View File
@@ -45,7 +45,6 @@ IF "%1"=="vc14" SET TOOLSET=msvc : 14.0
IF "%1"=="vc141" SET TOOLSET=msvc : 14.1
IF "%1"=="vc142" SET TOOLSET=msvc : 14.2
IF "%1"=="vc143" SET TOOLSET=msvc : 14.3
IF "%1"=="vc145" SET TOOLSET=msvc : 14.5
ECHO.
ECHO Generating Boost.Build configuration in project-config.jam for %TOOLSET%...
+1 -1
View File
@@ -198,7 +198,7 @@ explicit libraries ;
xinclude tools :
../tools/quickbook/doc//quickbook
../tools/boostbook/doc//boostbook
../tools/boostbook/doc/boostbook.xml
;
explicit tools ;
+2 -2
View File
@@ -7,10 +7,10 @@
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt) -->
<title>Redirect to generated documentation</title>
<meta http-equiv="refresh" content="0; URL=../../tools/boostbook/index.html">
<meta http-equiv="refresh" content="0; URL=http://www.boost.org/doc/libs/master/doc/html/boostbook.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="../../tools/boostbook/index.html">../../tools/boostbook/index.html</a>
<a href="http://www.boost.org/doc/libs/master/doc/html/boostbook.html">http://www.boost.org/doc/libs/master/doc/html/boostbook.html</a>
</body>
</html>
+96
View 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
+264
View File
@@ -0,0 +1,264 @@
name: CI
on:
pull_request:
push:
branches:
- master
- develop
- feature/**
env:
UBSAN_OPTIONS: print_stacktrace=1
jobs:
posix:
strategy:
fail-fast: false
matrix:
include:
- toolset: gcc-4.8
cxxstd: "11"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-4.8
- toolset: gcc-5
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-5
- toolset: gcc-6
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: g++-6
- toolset: gcc-7
cxxstd: "11,14,17"
os: ubuntu-20.04
install: g++-7
- toolset: gcc-8
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: g++-8
- toolset: gcc-9
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
- toolset: gcc-10
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: g++-10
- toolset: gcc-11
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: g++-11
- toolset: gcc-12
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install: g++-12
- toolset: gcc-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:23.04
install: g++-13
- toolset: clang
compiler: clang++-3.9
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-3.9
- toolset: clang
compiler: clang++-4.0
cxxstd: "11,14"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-4.0
- toolset: clang
compiler: clang++-5.0
cxxstd: "11,14,1z"
os: ubuntu-latest
container: ubuntu:18.04
install: clang-5.0
- toolset: clang
compiler: clang++-6.0
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-6.0
- toolset: clang
compiler: clang++-7
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-7
- toolset: clang
compiler: clang++-8
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-8
- toolset: clang
compiler: clang++-9
cxxstd: "11,14,17"
os: ubuntu-20.04
install: clang-9
- toolset: clang
compiler: clang++-10
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: clang-10
- toolset: clang
compiler: clang++-11
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: clang-11
- toolset: clang
compiler: clang++-12
cxxstd: "11,14,17,2a"
os: ubuntu-20.04
install: clang-12
- toolset: clang
compiler: clang++-13
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install: clang-13
- toolset: clang
compiler: clang++-14
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install: clang-14
- toolset: clang
compiler: clang++-15
cxxstd: "11,14,17,20,2b"
os: ubuntu-22.04
install: clang-15
- toolset: clang
compiler: clang++-16
cxxstd: "11,14,17,20,2b"
os: ubuntu-latest
container: ubuntu:23.04
install: clang-16
- toolset: clang
cxxstd: "11,14,17,2a"
os: macos-11
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-12
- toolset: clang
cxxstd: "11,14,17,20,2b"
os: macos-13
runs-on: ${{matrix.os}}
container: ${{matrix.container}}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- name: Setup container environment
if: matrix.container
run: |
apt-get update
apt-get -y install sudo python3 git g++
- name: Install packages
if: matrix.install
run: sudo apt-get -y install ${{matrix.install}}
- name: Setup Boost
run: |
echo GITHUB_REPOSITORY: $GITHUB_REPOSITORY
LIBRARY=${GITHUB_REPOSITORY#*/}
echo LIBRARY: $LIBRARY
echo "LIBRARY=$LIBRARY" >> $GITHUB_ENV
echo GITHUB_BASE_REF: $GITHUB_BASE_REF
echo GITHUB_REF: $GITHUB_REF
REF=${GITHUB_BASE_REF:-$GITHUB_REF}
REF=${REF#refs/heads/}
echo REF: $REF
BOOST_BRANCH=develop && [ "$REF" == "master" ] && BOOST_BRANCH=master || true
echo BOOST_BRANCH: $BOOST_BRANCH
cd ..
git clone -b $BOOST_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY
git submodule update --init tools/boostdep
python3 tools/boostdep/depinst/depinst.py --git_args "--jobs 3" $LIBRARY
./bootstrap.sh
./b2 -d0 headers
- name: Create user-config.jam
if: matrix.compiler
run: |
echo "using ${{matrix.toolset}} : : ${{matrix.compiler}} ;" > ~/user-config.jam
- name: Run tests
run: |
cd ../boost-root
./b2 -j3 libs/$LIBRARY/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} variant=debug,release
windows:
strategy:
fail-fast: false
matrix:
include:
- toolset: msvc-14.0
cxxstd: "14"
addrmd: 32,64
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 32
os: windows-2019
- toolset: msvc-14.2
cxxstd: "14,17,20,latest"
addrmd: 64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32
os: windows-2022
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 64
os: windows-2022
- toolset: clang-win
cxxstd: "14,17,latest"
addrmd: 32,64
os: windows-2022
- toolset: gcc
cxxstd: "11,14,17,2a"
addrmd: 64
os: windows-2019
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v3
- name: Setup Boost
shell: cmd
run: |
echo GITHUB_REPOSITORY: %GITHUB_REPOSITORY%
for /f %%i in ("%GITHUB_REPOSITORY%") do set LIBRARY=%%~nxi
echo LIBRARY: %LIBRARY%
echo LIBRARY=%LIBRARY%>>%GITHUB_ENV%
echo GITHUB_BASE_REF: %GITHUB_BASE_REF%
echo GITHUB_REF: %GITHUB_REF%
if "%GITHUB_BASE_REF%" == "" set GITHUB_BASE_REF=%GITHUB_REF%
set BOOST_BRANCH=develop
for /f %%i in ("%GITHUB_BASE_REF%") do if "%%~nxi" == "master" set BOOST_BRANCH=master
echo BOOST_BRANCH: %BOOST_BRANCH%
cd ..
git clone -b %BOOST_BRANCH% --depth 1 https://github.com/boostorg/boost.git boost-root
cd boost-root
xcopy /s /e /q %GITHUB_WORKSPACE% libs\%LIBRARY%\
git submodule update --init tools/boostdep
python tools/boostdep/depinst/depinst.py --git_args "--jobs 3" %LIBRARY%
cmd /c bootstrap
b2 -d0 headers
- name: Run tests
shell: cmd
run: |
cd ../boost-root
b2 -j3 libs/%LIBRARY%/test toolset=${{matrix.toolset}} cxxstd=${{matrix.cxxstd}} address-model=${{matrix.addrmd}} variant=debug,release embed-manifest-via=linker
+272
View File
@@ -0,0 +1,272 @@
# Copyright 2018 Cromwell D. Enage
# 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
python: "2.7"
branches:
only:
- master
- develop
- /feature\/.*/
env:
matrix:
- BOGUS_JOB=true
matrix:
exclude:
- env: BOGUS_JOB=true
include:
- os: linux
compiler: g++-4.4
env: TOOLSET=gcc COMPILER=g++-4.4 CXXSTD=98,0x
addons:
apt:
packages:
- g++-4.4
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-4.6
env: TOOLSET=gcc COMPILER=g++-4.6 CXXSTD=03,0x
addons:
apt:
packages:
- g++-4.6
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-4.7 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.7
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-4.8 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.8
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-4.9 CXXSTD=03,11
addons:
apt:
packages:
- g++-4.9
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-5 CXXSTD=03,11,14
addons:
apt:
packages:
- g++-5
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=gcc COMPILER=g++-6 CXXSTD=03,11,14,1z CXXSTD_DIALECT=cxxstd-dialect=gnu
addons:
apt:
packages:
- g++-6
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: trusty
compiler: g++-7
env: TOOLSET=gcc COMPILER=g++-7 CXXSTD=03,11,14,17 CXXSTD_DIALECT=cxxstd-dialect=gnu
addons:
apt:
packages:
- g++-7
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: g++-8
env: TOOLSET=gcc COMPILER=g++-8 CXXSTD=03,11,14,17
addons:
apt:
packages:
- g++-8
sources:
- ubuntu-toolchain-r-test
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.5 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.5
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.5
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.6 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.6
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.6
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.7 CXXSTD=03,11
addons:
apt:
packages:
- clang-3.7
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.7
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.8 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.8
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.8
- os: linux
env: TOOLSET=clang COMPILER=clang++-3.9 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-3.9
- libstdc++-4.9-dev
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-precise-3.9
- os: linux
compiler: clang++-4.0
env: TOOLSET=clang COMPILER=clang++-4.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-4.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-4.0
- os: linux
compiler: clang++-5.0
env: TOOLSET=clang COMPILER=clang++-5.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-5.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-5.0
- os: linux
compiler: clang++-6.0
env: TOOLSET=clang COMPILER=clang++-6.0 CXXSTD=03,11,14,1z
addons:
apt:
packages:
- clang-6.0
sources:
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty-6.0
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
addons:
apt:
packages:
- libstdc++-5-dev
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,1z
addons:
apt:
packages:
- libc++-dev
- os: osx
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
osx_image: xcode7.3
- os: osx
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
osx_image: xcode8.3
- os: osx
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z
osx_image: xcode9.4.1
install:
- BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true
- cd ..
- git clone -b $TRAVIS_BRANCH --depth 1 https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/boost_install
- git submodule update --init libs/headers
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- cp -r $TRAVIS_BUILD_DIR/* libs/accumulators
- python tools/boostdep/depinst/depinst.py accumulators
- ./bootstrap.sh
- ./b2 headers
script:
- |-
echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam
- ./b2 --verbose-test libs/config/test//config_info toolset=$TOOLSET cxxstd=$CXXSTD || true
- cd libs/accumulators/test
- ../../../b2 -j`(nproc || sysctl -n hw.ncpu) 2> /dev/null` toolset=$TOOLSET cxxstd=$CXXSTD $CXXSTD_DIALECT
- cd ../../..
notifications:
email:
on_success: always
+44
View File
@@ -0,0 +1,44 @@
# Generated by `boostdep --cmake accumulators`
# Copyright 2020 Peter Dimov
# 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_accumulators VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
add_library(boost_accumulators INTERFACE)
add_library(Boost::accumulators ALIAS boost_accumulators)
target_include_directories(boost_accumulators INTERFACE include)
target_link_libraries(boost_accumulators
INTERFACE
Boost::array
Boost::assert
Boost::circular_buffer
Boost::concept_check
Boost::config
Boost::core
Boost::fusion
Boost::iterator
Boost::mpl
Boost::numeric_conversion
Boost::numeric_ublas
Boost::parameter
Boost::preprocessor
Boost::range
Boost::serialization
Boost::static_assert
Boost::throw_exception
Boost::tuple
Boost::type_traits
Boost::typeof
)
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
add_subdirectory(test)
endif()
+67
View File
@@ -0,0 +1,67 @@
# Copyright 2018 Cromwell D. Enage
# 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)
version: 1.0.{build}-{branch}
shallow_clone: true
branches:
only:
- master
- develop
environment:
matrix:
- ARGS: --toolset=gcc address-model=32
PATH: C:\mingw-w64\i686-5.3.0-posix-dwarf-rt_v4-rev0\mingw32\bin;%PATH%
- ARGS: --toolset=gcc address-model=32 linkflags=-Wl,-allow-multiple-definition
PATH: C:\MinGW\bin;%PATH%
- ARGS: --toolset=gcc address-model=64
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
- ARGS: --toolset=gcc address-model=64 cxxflags=-std=gnu++1z
PATH: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin;%PATH%
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
ARGS: --toolset=msvc-9.0 address-model=32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
ARGS: --toolset=msvc-10.0 address-model=32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
ARGS: --toolset=msvc-11.0 address-model=32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
ARGS: --toolset=msvc-12.0 address-model=32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
ARGS: --toolset=msvc-12.0 address-model=64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ARGS: --toolset=msvc-14.0 address-model=32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ARGS: --toolset=msvc-14.0 address-model=64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ARGS: --toolset=msvc-14.0 address-model=64 cxxflags=-std:c++latest
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ARGS: --toolset=msvc-14.1 address-model=32
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ARGS: --toolset=msvc-14.1 address-model=64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
ARGS: --toolset=msvc-14.1 address-model=64 cxxflags=-std:c++latest
install:
- cd ..
- git clone -b %APPVEYOR_REPO_BRANCH% https://github.com/boostorg/boost.git boost-root
- cd boost-root
- git submodule update --init tools/boost_install
- git submodule update --init libs/headers
- git submodule update --init tools/build
- git submodule update --init libs/config
- git submodule update --init tools/boostdep
- xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\accumulators
- python tools/boostdep/depinst/depinst.py accumulators
- bootstrap
- b2 headers
build: off
test_script:
- cd libs\accumulators\test
- ..\..\..\b2 -j%NUMBER_OF_PROCESSORS% --hash %ARGS%
- cd ..\..\..
+257
View File
@@ -0,0 +1,257 @@
# Copyright Eric Niebler 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)
import os ;
import common ;
import doxygen ;
import quickbook ;
#
# Accumulators docs are dependent upon
# latex dvips and ps being in your PATH.
# This is true for most Unix installs, but
# not on Win32, where you will need to install
# MkTex and Ghostscript and add these tools
# to your path.
#
make latex.check : : @check-latex ;
actions check-latex
{
latex -version > latex.version
}
make dvips.check : : @check-dvips ;
actions check-dvips
{
dvips -version > dvips.version
}
make gs.check : : @check-gs ;
import os ;
if [ os.name ] = "NT"
{
actions check-gs
{
gswin32c -version > gs.version
}
}
else
{
actions check-gs
{
gs -version > gs.version
}
}
# Use Doxygen to emit a tagfile with the definition of depends_on<>. That
# tagfile will be used by Doxygen below when generating the Statistics Library
# Reference. This is all so that the Doxygen-generated documentation for the
# features shows the dependency relationships between them.
doxygen tagfile
:
../../../boost/accumulators/framework/depends_on.hpp
../../../boost/accumulators/framework/extractor.hpp
:
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>GENERATE_TAGFILE=accumulators.tag
<doxygen:param>"PREDEFINED=\"BOOST_ACCUMULATORS_DOXYGEN_INVOKED=1\" \\
\"BOOST_PP_REPEAT_FROM_TO(a,b,c,d)=\" \\
\"BOOST_PP_ENUM_PARAMS(a,b)=b ## 1, b ## 2, ...\""
<dependency>latex.check
<dependency>dvips.check
<dependency>gs.check
;
doxygen accdoc
:
[ glob ../../../boost/accumulators/accumulators*.hpp ]
[ glob ../../../boost/accumulators/framework/*.hpp ]
[ glob ../../../boost/accumulators/framework/parameters/*.hpp ]
[ glob ../../../boost/accumulators/framework/accumulators/*.hpp ]
:
<doxygen:param>EXTRACT_ALL=YES
<doxygen:param>"PREDEFINED=\"BOOST_ACCUMULATORS_DOXYGEN_INVOKED=1\" \\
\"BOOST_PP_REPEAT_FROM_TO(a,b,c,d)=\" \\
\"BOOST_PP_REPEAT(a,b,c)=\" \\
\"BOOST_PARAMETER_KEYWORD(a,b)=\\
namespace a { struct b {}; } \\
boost::parameter::keyword<a::b> const b;\" \\
\"BOOST_PP_ENUM_PARAMS(a,b)=b ## 1, b ## 2, ...\""
<doxygen:param>HIDE_UNDOC_MEMBERS=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>SEARCH_INCLUDES=NO
<reftitle>"Accumulators Framework Reference"
<dependency>latex.check
<dependency>dvips.check
<dependency>gs.check
;
# Generate the HTML form of the stats documentation, as this causes Doxygen to
# generate .png images for the LaTeX formulas embedded in the doc comments.
doxygen statsdoc.html
:
[ glob ../../../boost/accumulators/statistics*.hpp ]
[ glob ../../../boost/accumulators/statistics/*.hpp ]
[ glob ../../../boost/accumulators/statistics/variates/*.hpp ]
:
<dependency>latex.check
<dependency>dvips.check
<dependency>gs.check
;
if [ os.name ] = NT
{
CP = copy /y ;
MKDIR = mkdir ;
FROM = \\..\\..\\..\\html\\statsdoc\\*.png ;
TOHTML = .\\html\\images\\accumulators ;
TOPDF = \\images\\accumulators ;
}
else
{
CP = cp ;
MKDIR = mkdir -p ;
FROM = /../../html/statsdoc/*.png ;
TOHTML = ./html/images/accumulators ;
TOPDF = /images/accumulators ;
}
actions copy-latex-pngs
{
$(MKDIR) $(TOHTML)
$(MKDIR) $(<:D)$(TOPDF)
$(CP) $(<:D)$(FROM) $(TOHTML)
$(CP) $(<:D)$(FROM) $(<:D)$(TOPDF)
echo "Stamped" > "$(<)"
}
# This causes the png files built above to be copied into the
# html/images/accumulators directory.
make statsdoclatex.tag
: statsdoc.html
: @copy-latex-pngs
;
doxygen statsdoc
:
[ glob ../../../boost/accumulators/statistics*.hpp ]
[ glob ../../../boost/accumulators/statistics/*.hpp ]
[ glob ../../../boost/accumulators/statistics/variates/*.hpp ]
:
<doxygen:param>EXTRACT_ALL=YES
<doxygen:param>"PREDEFINED=\"BOOST_ACCUMULATORS_DOXYGEN_INVOKED=1\" \\
\"BOOST_PP_REPEAT_FROM_TO(a,b,c,d)=\" \\
\"BOOST_PP_REPEAT(a,b,c)=\" \\
\"BOOST_PARAMETER_KEYWORD(a,b)=\\
namespace a { struct b {}; } \\
boost::parameter::keyword<a::b> const b;\" \\
\"BOOST_PP_ENUM_PARAMS(a,b)=b ## 1, b ## 2, ...\""
<doxygen:param>HIDE_UNDOC_MEMBERS=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>SEARCH_INCLUDES=NO
<doxygen:param>TAGFILES=accumulators.tag
<xsl:param>boost.doxygen.formuladir=images/accumulators/
<reftitle>"Statistics Library Reference"
<dependency>tagfile
<dependency>statsdoclatex.tag
<dependency>latex.check
<dependency>dvips.check
<dependency>gs.check
;
doxygen opdoc
:
[ glob ../../../boost/accumulators/numeric/functional.hpp ]
[ glob ../../../boost/accumulators/numeric/functional/*.hpp ]
:
<doxygen:param>EXTRACT_ALL=YES
<doxygen:param>"PREDEFINED=\"BOOST_NUMERIC_FUNCTIONAL_DOXYGEN_INVOKED=1\" \\
\"BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(a,b,c)=\\
namespace functional { \\
template<class Left,class Right,class EnableIf=void> struct a ## _base \\
: std::binary_function<Left, Right, typeof(lvalue<Left>() b lvalue<Right>())> { \\
/** \\return left b right */ \\
result_type operator()(Left &left, Right &right) const; }; \\
template<class Left,class Right, \\
class LeftTag=typename tag<Left>::type, \\
class RightTag=typename tag<Right>::type> \\
struct a : a ## _base<Left,Right,void> {}; } \\
namespace op { \\
struct a : boost::detail::function2< \\
functional::a<_1,_2,functional::tag<_1>,functional::tag<_2> > > {}; } \\
namespace { \\
/** \\return functional::a<Left, Right>()(left, right) */ \\
op::a const & a = boost::detail::pod_singleton<op::min_assign>::instance; } \" \\
\"BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(a,b)=\\
namespace functional { \\
template<class Arg,class EnableIf=void> struct a ## _base \\
: std::unary_function<Arg, typeof(b lvalue<Arg>())> { \\
/** \\return b arg */ \\
result_type operator()(Arg & arg) const; }; \\
template<class Arg,class Tag=typename tag<Arg>::type> \\
struct a : a ## _base<Arg,void> {}; } \\
namespace op { \\
struct a : boost::detail::function1< \\
functional::a<_,functional::tag<_> > > {}; } \\
namespace { \\
/** \\return functional::a<Arg>()(arg) */ \\
op::a const & a = boost::detail::pod_singleton<op::min_assign>::instance; }\""
<doxygen:param>HIDE_UNDOC_MEMBERS=NO
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>ENABLE_PREPROCESSING=YES
<doxygen:param>MACRO_EXPANSION=YES
<doxygen:param>EXPAND_ONLY_PREDEF=YES
<doxygen:param>SEARCH_INCLUDES=NO
<reftitle>"Numeric Operators Library Reference"
<dependency>latex.check
<dependency>dvips.check
<dependency>gs.check
;
xml accumulators
:
accumulators.qbk
:
<xsl:param>boost.max.id.length=1024
<xsl:param>toc.max.depth=4
<xsl:param>toc.section.depth=4
<xsl:param>chunk.section.depth=2
;
path-constant images_location : html ;
boostbook standalone
:
accumulators
:
<xsl:param>boost.root=../../../..
<xsl:param>boost.max.id.length=1024
<xsl:param>toc.max.depth=4
<xsl:param>toc.section.depth=4
<xsl:param>chunk.section.depth=2
<dependency>accdoc
<dependency>statsdoc
<dependency>opdoc
<format>pdf:<xsl:param>img.src.path=$(images_location)/
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/doc/html
;
###############################################################################
alias boostdoc
: accumulators
:
: <dependency>accdoc <dependency>statsdoc <dependency>opdoc
: ;
explicit boostdoc ;
alias boostrelease ;
explicit boostrelease ;
File diff suppressed because it is too large Load Diff
+13
View File
@@ -0,0 +1,13 @@
# (C) Copyright 2004: Eric Niebler
# 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)
exe example
:
main.cpp
:
<include>../../..
<include>$(BOOST_ROOT)
<library>/boost/serialization
<cxxflags>"-Wno-deprecated-declarations"
;
+396
View File
@@ -0,0 +1,396 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="example"
ProjectGUID="{57D2AB8B-8CBB-4B28-921E-C6916109B843}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..;$(BOOST_ROOT)"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/example.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/example.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="..\..\..;$(BOOST_ROOT)"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/example.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\main.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\..\..\boost\accumulators\accumulators.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\accumulators_fwd.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics_fwd.hpp">
</File>
<Filter
Name="statistics"
Filter="">
<File
RelativePath="..\..\..\boost\accumulators\statistics\count.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\covariance.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\density.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\error_of.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\error_of_mean.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\extended_p_square.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\extended_p_square_quantile.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\kurtosis.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\max.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\mean.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\median.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\min.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\moment.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\p_square_cumulative_distribution.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\p_square_quantile.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\peaks_over_threshold.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\pot_quantile.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\pot_tail_mean.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\skewness.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\stats.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\sum.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\tail.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\tail_mean.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\tail_quantile.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\tail_variate.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\tail_variate_means.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\times2_iterator.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\variance.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_covariance.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_density.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_extended_p_square.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_kurtosis.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_mean.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_median.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_moment.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_p_square_cumulative_distribution.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_p_square_quantile.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_peaks_over_threshold.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_skewness.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_sum.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_tail_mean.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_tail_quantile.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_tail_variate_means.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\weighted_variance.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\statistics\with_error.hpp">
</File>
<Filter
Name="variates"
Filter="">
<File
RelativePath="..\..\..\boost\accumulators\statistics\variates\covariate.hpp">
</File>
</Filter>
<Filter
Name="parameters"
Filter="">
<File
RelativePath="..\..\..\boost\accumulators\statistics\parameters\quantile_probability.hpp">
</File>
</Filter>
</Filter>
<Filter
Name="framework"
Filter="">
<File
RelativePath="..\..\..\boost\accumulators\framework\accumulator_base.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\accumulator_concept.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\accumulator_set.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\depends_on.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\external.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\extractor.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\features.hpp">
</File>
<Filter
Name="parameters"
Filter="">
<File
RelativePath="..\..\..\boost\accumulators\framework\parameters\accumulator.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\parameters\sample.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\parameters\weight.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\parameters\weights.hpp">
</File>
</Filter>
<Filter
Name="accumulators"
Filter="">
<File
RelativePath="..\..\..\boost\accumulators\framework\accumulators\droppable_accumulator.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\accumulators\external_accumulator.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\accumulators\reference_accumulator.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\framework\accumulators\value_accumulator.hpp">
</File>
</Filter>
</Filter>
<Filter
Name="numeric"
Filter="">
<File
RelativePath="..\..\..\boost\accumulators\numeric\functional.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\numeric\functional_fwd.hpp">
</File>
<Filter
Name="functional"
Filter="">
<File
RelativePath="..\..\..\boost\accumulators\numeric\functional\complex.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\numeric\functional\valarray.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\numeric\functional\vector.hpp">
</File>
</Filter>
<Filter
Name="detail"
Filter="">
<File
RelativePath="..\..\..\boost\accumulators\numeric\detail\function1.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\numeric\detail\function2.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\numeric\detail\function3.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\numeric\detail\function4.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\numeric\detail\function_n.hpp">
</File>
<File
RelativePath="..\..\..\boost\accumulators\numeric\detail\pod_singleton.hpp">
</File>
</Filter>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
+262
View File
@@ -0,0 +1,262 @@
///////////////////////////////////////////////////////////////////////////////
// main.hpp
//
// Copyright 2005 Eric Niebler. 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)
#include <iostream>
#include <fstream> // needed for de/serialization example (4)
#include <algorithm>
#include <boost/ref.hpp>
#include <boost/bind.hpp>
#include <boost/array.hpp>
#include <boost/foreach.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
// needed for de/serialization example (4)
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
using namespace boost;
using namespace boost::accumulators;
// Helper that uses BOOST_FOREACH to display a range of doubles
template<typename Range>
void output_range(Range const &rng)
{
bool first = true;
BOOST_FOREACH(double d, rng)
{
if(!first) std::cout << ", ";
std::cout << d;
first = false;
}
std::cout << '\n';
}
///////////////////////////////////////////////////////////////////////////////
// example1
//
// Calculate some useful stats using accumulator_set<> and std::for_each()
//
void example1()
{
accumulator_set<
double
, stats<tag::min, tag::mean(immediate), tag::sum, tag::moment<2> >
> acc;
boost::array<double, 4> data = {0., 1., -1., 3.14159};
// std::for_each pushes each sample into the accumulator one at a
// time, and returns a copy of the accumulator.
acc = std::for_each(data.begin(), data.end(), acc);
// The following would be equivalent, and could be more efficient
// because it doesn't pass and return the entire accumulator set
// by value.
//std::for_each(data.begin(), data.end(), bind<void>(ref(acc), _1));
std::cout << " min""(acc) = " << (min)(acc) << std::endl; // Extra quotes are to prevent complaints from Boost inspect tool
std::cout << " mean(acc) = " << mean(acc) << std::endl;
// since mean depends on count and sum, we can get their results, too.
std::cout << " count(acc) = " << count(acc) << std::endl;
std::cout << " sum(acc) = " << sum(acc) << std::endl;
std::cout << " moment<2>(acc) = " << accumulators::moment<2>(acc) << std::endl;
}
///////////////////////////////////////////////////////////////////////////////
// example2
//
// Calculate some tail statistics. This demonstrates how to specify
// constructor and accumulator parameters. Note that the tail statistics
// return multiple values, which are returned in an iterator_range.
//
// It pushes data in and displays the intermediate results to demonstrate
// how the tail statistics are updated.
void example2()
{
// An accumulator which tracks the right tail (largest N items) and
// some data that are covariate with them. N == 4.
accumulator_set<
double
, stats<tag::tail_variate<double, tag::covariate1, right> >
> acc(tag::tail<right>::cache_size = 4);
acc(2.1, covariate1 = .21);
acc(1.1, covariate1 = .11);
acc(2.1, covariate1 = .21);
acc(1.1, covariate1 = .11);
std::cout << " tail = "; output_range(tail(acc));
std::cout << " tail_variate = "; output_range(tail_variate(acc));
std::cout << std::endl;
acc(21.1, covariate1 = 2.11);
acc(11.1, covariate1 = 1.11);
acc(21.1, covariate1 = 2.11);
acc(11.1, covariate1 = 1.11);
std::cout << " tail = "; output_range(tail(acc));
std::cout << " tail_variate = "; output_range(tail_variate(acc));
std::cout << std::endl;
acc(42.1, covariate1 = 4.21);
acc(41.1, covariate1 = 4.11);
acc(42.1, covariate1 = 4.21);
acc(41.1, covariate1 = 4.11);
std::cout << " tail = "; output_range(tail(acc));
std::cout << " tail_variate = "; output_range(tail_variate(acc));
std::cout << std::endl;
acc(32.1, covariate1 = 3.21);
acc(31.1, covariate1 = 3.11);
acc(32.1, covariate1 = 3.21);
acc(31.1, covariate1 = 3.11);
std::cout << " tail = "; output_range(tail(acc));
std::cout << " tail_variate = "; output_range(tail_variate(acc));
}
///////////////////////////////////////////////////////////////////////////////
// example3
//
// Demonstrate how to calculate weighted statistics. This example demonstrates
// both a simple weighted statistical calculation, and a more complicated
// calculation where the weight statistics are calculated and stored in an
// external weight accumulator.
void example3()
{
// weight == double
double w = 1.;
// Simple weighted calculation
{
// stats that depend on the weight are made external
accumulator_set<double, stats<tag::mean>, double> acc;
acc(0., weight = w);
acc(1., weight = w);
acc(-1., weight = w);
acc(3.14159, weight = w);
std::cout << " mean(acc) = " << mean(acc) << std::endl;
}
// Weighted calculation with an external weight accumulator
{
// stats that depend on the weight are made external
accumulator_set<double, stats<tag::mean>, external<double> > acc;
// Here's an external weight accumulator
accumulator_set<void, stats<tag::sum_of_weights>, double> weight_acc;
weight_acc(weight = w); acc(0., weight = w);
weight_acc(weight = w); acc(1., weight = w);
weight_acc(weight = w); acc(-1., weight = w);
weight_acc(weight = w); acc(3.14159, weight = w);
std::cout << " mean(acc) = " << mean(acc, weights = weight_acc) << std::endl;
}
}
///////////////////////////////////////////////////////////////////////////////
// example4
//
// Show how accumulators could be persisted into a file, and then continued
// from where they were left of
//
void example4()
{
accumulator_set<
double
, stats<tag::min, tag::mean(immediate), tag::sum, tag::moment<2>, tag::p_square_quantile, tag::kurtosis >
> acc(quantile_probability = 0.9);
{
// accumulate values from array
boost::array<double, 10> data = {-10., -8., -7., -6., -5., -4., -3., -2., -1., 0.};
acc = std::for_each(data.begin(), data.end(), acc);
}
std::cout << " min = " << (min)(acc) << std::endl;
std::cout << " mean = " << mean(acc) << std::endl;
std::cout << " count = " << count(acc) << std::endl;
std::cout << " sum = " << sum(acc) << std::endl;
std::cout << " moment<2> = " << accumulators::moment<2>(acc) << std::endl;
std::cout << " p_square_quantile = " << accumulators::p_square_quantile(acc) << std::endl;
std::cout << " kurtosis = " << accumulators::kurtosis(acc) << std::endl;
// save accumulator list into a file called "saved-stats"
const unsigned ACC_VER = 0;
const char* file_name = "saved-stats";
{
std::ofstream ofs(file_name);
boost::archive::text_oarchive oa(ofs);
acc.serialize(oa, ACC_VER);
}
// create a new accumulator set and initialize from data saved into the file
accumulator_set<
double
, stats<tag::min, tag::mean(immediate), tag::sum, tag::moment<2>, tag::p_square_quantile, tag::kurtosis >
> restored_acc(quantile_probability = 0.9);
{
std::ifstream ifs(file_name);
boost::archive::text_iarchive ia(ifs);
restored_acc.serialize(ia, ACC_VER);
}
// continue accumulating into both sets
{
// accumulate values from array
boost::array<double, 10> data = {10., 8., 7., 6., 5., 4., 3., 2., 1., 0.};
acc = std::for_each(data.begin(), data.end(), acc);
restored_acc = std::for_each(data.begin(), data.end(), restored_acc);
}
// validate that both return th same values
std::cout << std::endl << "Values in original set:" << std::endl;
std::cout << " min""(acc) = " << (min)(acc) << std::endl;
std::cout << " mean(acc) = " << mean(acc) << std::endl;
std::cout << " count(acc) = " << count(acc) << std::endl;
std::cout << " sum(acc) = " << sum(acc) << std::endl;
std::cout << " moment<2>(acc) = " << accumulators::moment<2>(acc) << std::endl;
std::cout << " p_square_quantile(acc) = " << accumulators::p_square_quantile(acc) << std::endl;
std::cout << " kurtosis(acc) = " << accumulators::kurtosis(acc) << std::endl;
std::cout << std::endl << "Values in restored set:" << std::endl;
std::cout << " min""(acc) = " << (min)(restored_acc) << std::endl;
std::cout << " mean(acc) = " << mean(restored_acc) << std::endl;
std::cout << " count(acc) = " << count(restored_acc) << std::endl;
std::cout << " sum(acc) = " << sum(restored_acc) << std::endl;
std::cout << " moment<2>(acc) = " << accumulators::moment<2>(restored_acc) << std::endl;
std::cout << " p_square_quantile(acc) = " << accumulators::p_square_quantile(restored_acc) << std::endl;
std::cout << " kurtosis(acc) = " << accumulators::kurtosis(restored_acc) << std::endl;
}
///////////////////////////////////////////////////////////////////////////////
// main
int main()
{
std::cout << "Example 1:\n";
example1();
std::cout << "\nExample 2:\n";
example2();
std::cout << "\nExample 3:\n";
example3();
std::cout << "\nExample 4:\n";
example4();
return 0;
}
@@ -0,0 +1,27 @@
///////////////////////////////////////////////////////////////////////////////
/// \file accumulators.hpp
/// Includes all of the Accumulators Framework
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_ACCUMULATORS_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_ACCUMULATORS_HPP_EAN_28_10_2005
#include <boost/accumulators/framework/accumulator_set.hpp>
#include <boost/accumulators/framework/accumulator_concept.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/external.hpp>
#include <boost/accumulators/framework/features.hpp>
#include <boost/accumulators/framework/parameters/accumulator.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/parameters/weight.hpp>
#include <boost/accumulators/framework/parameters/weights.hpp>
#include <boost/accumulators/framework/accumulators/external_accumulator.hpp>
#include <boost/accumulators/framework/accumulators/droppable_accumulator.hpp>
#include <boost/accumulators/framework/accumulators/reference_accumulator.hpp>
#include <boost/accumulators/framework/accumulators/value_accumulator.hpp>
#endif
@@ -0,0 +1,232 @@
///////////////////////////////////////////////////////////////////////////////
// accumulators_fwd.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_ACCUMULATORS_FWD_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_ACCUMULATORS_FWD_HPP_EAN_28_10_2005
#include <boost/config.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/parameter/is_argument_pack.hpp>
#include <boost/mpl/apply_fwd.hpp> // for mpl::na
#include <boost/mpl/limits/vector.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/accumulators/numeric/functional_fwd.hpp>
#ifndef BOOST_ACCUMULATORS_MAX_FEATURES
/// The maximum number of accumulators that may be put in an accumulator_set.
/// Defaults to BOOST_MPL_LIMIT_VECTOR_SIZE (which defaults to 20).
# define BOOST_ACCUMULATORS_MAX_FEATURES BOOST_MPL_LIMIT_VECTOR_SIZE
#endif
#if BOOST_ACCUMULATORS_MAX_FEATURES > BOOST_MPL_LIMIT_VECTOR_SIZE
# error BOOST_ACCUMULATORS_MAX_FEATURES cannot be larger than BOOST_MPL_LIMIT_VECTOR_SIZE
#endif
#ifndef BOOST_ACCUMULATORS_MAX_ARGS
/// The maximum number of arguments that may be specified to an accumulator_set's
/// accumulation function. Defaults to 15.
# define BOOST_ACCUMULATORS_MAX_ARGS 15
#endif
#if BOOST_WORKAROUND(__GNUC__, == 3) \
|| BOOST_WORKAROUND(__EDG_VERSION__, BOOST_TESTED_AT(306))
# define BOOST_ACCUMULATORS_BROKEN_CONST_OVERLOADS
#endif
#ifdef BOOST_ACCUMULATORS_BROKEN_CONST_OVERLOADS
# include <boost/type_traits/is_const.hpp>
# define BOOST_ACCUMULATORS_PROTO_DISABLE_IF_IS_CONST(T)\
, typename boost::disable_if<boost::is_const<T> >::type * = 0
#else
# define BOOST_ACCUMULATORS_PROTO_DISABLE_IF_IS_CONST(T)
#endif
#define BOOST_ACCUMULATORS_GCC_VERSION \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////////
// Named parameters tags
//
namespace tag
{
struct sample;
struct weight;
struct accumulator;
struct weights;
}
///////////////////////////////////////////////////////////////////////////////
// User-level features
//
namespace tag
{
template<typename ValueType, typename Tag>
struct value;
template<typename Tag>
struct value_tag;
template<typename Referent, typename Tag>
struct reference;
template<typename Tag>
struct reference_tag;
template<typename Type, typename Tag = void, typename AccumulatorSet = void>
struct external;
template<typename Feature>
struct droppable;
}
template<typename Accumulator>
struct droppable_accumulator_base;
template<typename Accumulator>
struct droppable_accumulator;
template<typename Accumulator>
struct with_cached_result;
template<typename Sample, typename Features, typename Weight = void>
struct accumulator_set;
template<typename Feature>
struct extractor;
template<typename Feature>
struct feature_of;
template<typename Feature>
struct as_feature;
template<typename Feature>
struct as_weighted_feature;
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_ACCUMULATORS_MAX_FEATURES, typename Feature, mpl::na)>
struct depends_on;
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_ACCUMULATORS_MAX_FEATURES, typename Feature, mpl::na)>
struct features;
template<typename Feature, typename AccumulatorSet>
typename mpl::apply<AccumulatorSet, Feature>::type const &
find_accumulator(AccumulatorSet const &acc);
template<typename Feature, typename AccumulatorSet>
typename mpl::apply<AccumulatorSet, Feature>::type::result_type
extract_result(AccumulatorSet const &acc);
namespace detail
{
struct _enabler
{
};
}
// ... other overloads generated by Boost.Preprocessor:
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_EXTRACT_RESULT_FWD(z, n, _) \
template< \
typename Feature \
, typename AccumulatorSet \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \
> \
typename mpl::apply<AccumulatorSet, Feature>::type::result_type \
extract_result( \
AccumulatorSet const &acc \
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) \
, typename boost::enable_if< \
parameter::is_argument_pack<A0> \
, detail::_enabler \
>::type = detail::_enabler() \
); \
template< \
typename Feature \
, typename AccumulatorSet \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \
> \
typename mpl::apply<AccumulatorSet, Feature>::type::result_type \
extract_result( \
AccumulatorSet const &acc \
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) \
, typename boost::disable_if< \
parameter::is_argument_pack<A0> \
, detail::_enabler \
>::type = detail::_enabler() \
);
/// INTERNAL ONLY
///
BOOST_PP_REPEAT_FROM_TO(
1
, BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS)
, BOOST_ACCUMULATORS_EXTRACT_RESULT_FWD
, _
)
#undef BOOST_ACCUMULATORS_EXTRACT_RESULT_FWD
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
template<typename Feature, typename AccumulatorSet, typename A1, typename A2 ...>
typename mpl::apply<AccumulatorSet, Feature>::type::result_type
extract_result(AccumulatorSet const &acc, A1 const &a1, A2 const &a2 ...);
#endif
namespace impl
{
using namespace numeric::operators;
template<typename Accumulator, typename Tag>
struct external_impl;
}
namespace detail
{
template<typename Accumulator>
struct feature_tag;
template<typename Feature, typename Sample, typename Weight>
struct to_accumulator;
struct accumulator_set_base;
template<typename T>
struct is_accumulator_set;
inline void ignore_variable(void const *) {}
}
}} // namespace boost::accumulators
#define BOOST_ACCUMULATORS_IGNORE_GLOBAL(X) \
namespace detail \
{ \
struct BOOST_PP_CAT(ignore_, X) \
{ \
void ignore() \
{ \
boost::accumulators::detail::ignore_variable(&X); \
} \
}; \
} \
/**/
#include <boost/parameter/nested_keyword.hpp>
#endif // include guard
@@ -0,0 +1,65 @@
///////////////////////////////////////////////////////////////////////////////
// accumulator_base.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_BASE_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_BASE_HPP_EAN_28_10_2005
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/single_view.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/empty_sequence.hpp>
#include <boost/accumulators/framework/accumulator_concept.hpp>
namespace boost { namespace accumulators
{
namespace detail
{
typedef void void_;
}
///////////////////////////////////////////////////////////////////////////////
// dont_care
//
struct dont_care
{
template<typename Args>
dont_care(Args const &)
{
}
};
///////////////////////////////////////////////////////////////////////////////
// accumulator_base
//
struct accumulator_base
{
// hidden if defined in derived classes
detail::void_ operator ()(dont_care)
{
}
typedef mpl::false_ is_droppable;
detail::void_ add_ref(dont_care)
{
}
detail::void_ drop(dont_care)
{
}
detail::void_ on_drop(dont_care)
{
}
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,29 @@
///////////////////////////////////////////////////////////////////////////////
// accumulator_concept.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_ACCUMULATOR_CONCEPT_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_ACCUMULATOR_CONCEPT_HPP_EAN_28_10_2005
#include <boost/concept_check.hpp>
namespace boost { namespace accumulators
{
template<typename Stat>
struct accumulator_concept
{
void constraints()
{
// TODO: define the stat concept
}
Stat stat;
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,549 @@
///////////////////////////////////////////////////////////////////////////////
// accumulator_set.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_ACCUMULATOR_SET_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_ACCUMULATOR_SET_HPP_EAN_28_10_2005
#include <boost/version.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/protect.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/parameter/is_argument_pack.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/framework/accumulator_concept.hpp>
#include <boost/accumulators/framework/parameters/accumulator.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/accumulators/external_accumulator.hpp>
#include <boost/accumulators/framework/accumulators/droppable_accumulator.hpp>
#include <boost/fusion/include/any.hpp>
#include <boost/fusion/include/find_if.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/filter_view.hpp>
namespace boost { namespace accumulators
{
namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// accumulator_visitor
// wrap a boost::parameter argument pack in a Fusion extractor object
template<typename Args>
struct accumulator_visitor
{
explicit accumulator_visitor(Args const &a)
: args(a)
{
}
accumulator_visitor(accumulator_visitor const &other)
: args(other.args)
{
}
template<typename Accumulator>
void operator ()(Accumulator &accumulator) const
{
accumulator(this->args);
}
private:
BOOST_DELETED_FUNCTION(accumulator_visitor &operator =(accumulator_visitor const &))
Args const &args;
};
template<typename Args>
inline accumulator_visitor<Args> const make_accumulator_visitor(Args const &args)
{
return accumulator_visitor<Args>(args);
}
///////////////////////////////////////////////////////////////////////////////
// accumulator_set_base
struct accumulator_set_base
{
};
///////////////////////////////////////////////////////////////////////////////
// is_accumulator_set
template<typename T>
struct is_accumulator_set
: mpl::if_<
boost::is_base_of<
accumulator_set_base
, typename boost::remove_const<
typename boost::remove_reference<T>::type
>::type
>
, mpl::true_
, mpl::false_
>::type
{
};
// function object that serialize an accumulator
template<typename Archive>
struct serialize_accumulator
{
serialize_accumulator(Archive & _ar, const unsigned int _file_version) :
ar(_ar), file_version(_file_version)
{}
template<typename Accumulator>
void operator ()(Accumulator &accumulator)
{
accumulator.serialize(ar, file_version);
}
private:
Archive& ar;
const unsigned int file_version;
};
} // namespace detail
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4355) // warning C4355: 'this' : used in base member initializer list
#endif
///////////////////////////////////////////////////////////////////////////////
/// \brief A set of accumulators.
///
/// accumulator_set resolves the dependencies between features and ensures that
/// the accumulators in the set are updated in the proper order.
///
/// acccumulator_set provides a general mechanism to visit the accumulators
/// in the set in order, with or without a filter. You can also fetch a reference
/// to an accumulator that corresponds to a feature.
///
template<typename Sample, typename Features, typename Weight>
struct accumulator_set
: detail::accumulator_set_base
{
typedef Sample sample_type; ///< The type of the samples that will be accumulated
typedef Features features_type; ///< An MPL sequence of the features that should be accumulated.
typedef Weight weight_type; ///< The type of the weight parameter. Must be a scalar. Defaults to void.
/// INTERNAL ONLY
///
typedef
typename detail::make_accumulator_tuple<
Features
, Sample
, Weight
>::type
accumulators_mpl_vector;
// generate a fusion::list of accumulators
/// INTERNAL ONLY
///
typedef
typename detail::meta::make_acc_list<
accumulators_mpl_vector
>::type
accumulators_type;
/// INTERNAL ONLY
///
//BOOST_MPL_ASSERT((mpl::is_sequence<accumulators_type>));
///////////////////////////////////////////////////////////////////////////////
/// default-construct all contained accumulators
accumulator_set()
: accumulators(
detail::make_acc_list(
accumulators_mpl_vector()
, (boost::accumulators::accumulator = *this)
)
)
{
// Add-ref the Features that the user has specified
this->template visit_if<detail::contains_feature_of_<Features> >(
detail::make_add_ref_visitor(boost::accumulators::accumulator = *this)
);
}
/// \overload
///
/// \param a1 Optional named parameter to be passed to all the accumulators
template<typename A1>
explicit accumulator_set(
A1 const &a1
, typename boost::enable_if<
parameter::is_argument_pack<A1>
, detail::_enabler
>::type = detail::_enabler()
) : accumulators(
detail::make_acc_list(
accumulators_mpl_vector()
, (boost::accumulators::accumulator = *this, a1)
)
)
{
// Add-ref the Features that the user has specified
this->template visit_if<detail::contains_feature_of_<Features> >(
detail::make_add_ref_visitor(boost::accumulators::accumulator = *this)
);
}
/// \overload
///
/// \param a1 Optional sample parameter to be passed to all the accumulators
template<typename A1>
explicit accumulator_set(
A1 const &a1
, typename boost::disable_if<
parameter::is_argument_pack<A1>
, detail::_enabler
>::type = detail::_enabler()
) : accumulators(
detail::make_acc_list(
accumulators_mpl_vector()
, (
boost::accumulators::accumulator = *this
, boost::accumulators::sample = a1
)
)
)
{
// Add-ref the Features that the user has specified
this->template visit_if<detail::contains_feature_of_<Features> >(
detail::make_add_ref_visitor(boost::accumulators::accumulator = *this)
);
}
// ... other overloads generated by Boost.Preprocessor:
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_ACCUMULATOR_SET_CTOR(z, n, _) \
template<BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
accumulator_set( \
BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, A, const &a) \
, typename boost::enable_if< \
parameter::is_argument_pack<A0> \
, detail::_enabler \
>::type = detail::_enabler() \
) : accumulators( \
detail::make_acc_list( \
accumulators_mpl_vector() \
, ( \
boost::accumulators::accumulator = *this \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a) \
) \
) \
) \
{ \
/* Add-ref the Features that the user has specified */ \
this->template visit_if<detail::contains_feature_of_<Features> >( \
detail::make_add_ref_visitor(boost::accumulators::accumulator = *this) \
); \
} \
template<BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
accumulator_set( \
BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, A, const &a) \
, typename boost::disable_if< \
parameter::is_argument_pack<A0> \
, detail::_enabler \
>::type = detail::_enabler() \
) : accumulators( \
detail::make_acc_list( \
accumulators_mpl_vector() \
, ( \
boost::accumulators::accumulator = *this \
, boost::accumulators::sample = BOOST_PP_ENUM_PARAMS_Z(z, n, a) \
) \
) \
) \
{ \
/* Add-ref the Features that the user has specified */ \
this->template visit_if<detail::contains_feature_of_<Features> >( \
detail::make_add_ref_visitor(boost::accumulators::accumulator = *this) \
); \
}
/// INTERNAL ONLY
///
BOOST_PP_REPEAT_FROM_TO(
2
, BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS)
, BOOST_ACCUMULATORS_ACCUMULATOR_SET_CTOR
, _
)
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// \overload
///
template<typename A1, typename A2, ...>
accumulator_set(A1 const &a1, A2 const &a2, ...);
#endif
// ... other overloads generated by Boost.Preprocessor below ...
///////////////////////////////////////////////////////////////////////////////
/// Visitation
/// \param func UnaryFunction which is invoked with each accumulator in turn.
template<typename UnaryFunction>
void visit(UnaryFunction const &func)
{
fusion::for_each(this->accumulators, func);
}
///////////////////////////////////////////////////////////////////////////////
/// Conditional visitation
/// \param func UnaryFunction which is invoked with each accumulator in turn,
/// provided the accumulator satisfies the MPL predicate FilterPred.
template<typename FilterPred, typename UnaryFunction>
void visit_if(UnaryFunction const &func)
{
fusion::filter_view<accumulators_type, FilterPred> filtered_accs(this->accumulators);
fusion::for_each(filtered_accs, func);
}
///////////////////////////////////////////////////////////////////////////////
/// The return type of the operator() overloads is void.
typedef void result_type;
///////////////////////////////////////////////////////////////////////////////
/// Accumulation
/// \param a1 Optional named parameter to be passed to all the accumulators
void operator ()()
{
this->visit(
detail::make_accumulator_visitor(
boost::accumulators::accumulator = *this
)
);
}
// ... other overloads generated by Boost.Preprocessor:
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_ACCUMULATOR_SET_FUN_OP(z, n, _) \
template<BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
void operator ()( \
BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, A, const &a) \
, typename boost::enable_if< \
parameter::is_argument_pack<A0> \
, detail::_enabler \
>::type = detail::_enabler() \
) \
{ \
this->visit( \
detail::make_accumulator_visitor( \
( \
boost::accumulators::accumulator = *this \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a) \
) \
) \
); \
} \
template<BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
void operator ()( \
BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, A, const &a) \
, typename boost::disable_if< \
parameter::is_argument_pack<A0> \
, detail::_enabler \
>::type = detail::_enabler() \
) \
{ \
this->visit( \
detail::make_accumulator_visitor( \
( \
boost::accumulators::accumulator = *this \
, boost::accumulators::sample = BOOST_PP_ENUM_PARAMS_Z(z, n, a) \
) \
) \
); \
}
/// INTERNAL ONLY
///
BOOST_PP_REPEAT_FROM_TO(
1
, BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS)
, BOOST_ACCUMULATORS_ACCUMULATOR_SET_FUN_OP
, _
)
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// \overload
///
template<typename A1, typename A2, ...>
void operator ()(A1 const &a1, A2 const &a2, ...);
#endif
///////////////////////////////////////////////////////////////////////////////
/// Extraction
template<typename Feature>
struct apply
: fusion::result_of::value_of<
typename fusion::result_of::find_if<
accumulators_type
, detail::matches_feature<Feature>
>::type
>
{
};
///////////////////////////////////////////////////////////////////////////////
/// Extraction
template<typename Feature>
typename apply<Feature>::type &extract()
{
return *fusion::find_if<detail::matches_feature<Feature> >(this->accumulators);
}
/// \overload
template<typename Feature>
typename apply<Feature>::type const &extract() const
{
return *fusion::find_if<detail::matches_feature<Feature> >(this->accumulators);
}
///////////////////////////////////////////////////////////////////////////////
/// Drop
template<typename Feature>
void drop()
{
// You can only drop the features that you have specified explicitly
typedef typename apply<Feature>::type the_accumulator;
BOOST_MPL_ASSERT((detail::contains_feature_of<Features, the_accumulator>));
typedef
typename feature_of<typename as_feature<Feature>::type>::type
the_feature;
(*fusion::find_if<detail::matches_feature<Feature> >(this->accumulators))
.drop(boost::accumulators::accumulator = *this);
// Also drop accumulators that this feature depends on
typedef typename the_feature::dependencies dependencies;
this->template visit_if<detail::contains_feature_of_<dependencies> >(
detail::make_drop_visitor(boost::accumulators::accumulator = *this)
);
}
// make the accumulator set serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
detail::serialize_accumulator<Archive> serializer(ar, file_version);
fusion::for_each(this->accumulators, serializer);
}
private:
accumulators_type accumulators;
};
#ifdef _MSC_VER
#pragma warning(pop)
#endif
///////////////////////////////////////////////////////////////////////////////
// find_accumulator
// find an accumulator in an accumulator_set corresponding to a feature
template<typename Feature, typename AccumulatorSet>
typename mpl::apply<AccumulatorSet, Feature>::type &
find_accumulator(AccumulatorSet &acc BOOST_ACCUMULATORS_PROTO_DISABLE_IF_IS_CONST(AccumulatorSet))
{
return acc.template extract<Feature>();
}
/// \overload
template<typename Feature, typename AccumulatorSet>
typename mpl::apply<AccumulatorSet, Feature>::type const &
find_accumulator(AccumulatorSet const &acc)
{
return acc.template extract<Feature>();
}
template<typename Feature, typename AccumulatorSet>
typename mpl::apply<AccumulatorSet, Feature>::type::result_type
extract_result(AccumulatorSet const &acc)
{
return find_accumulator<Feature>(acc).result(
boost::accumulators::accumulator = acc
);
}
///////////////////////////////////////////////////////////////////////////////
// extract_result
// extract a result from an accumulator set
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_EXTRACT_RESULT_FUN(z, n, _) \
template< \
typename Feature \
, typename AccumulatorSet \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \
> \
typename mpl::apply<AccumulatorSet, Feature>::type::result_type \
extract_result( \
AccumulatorSet const &acc \
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) \
, typename boost::enable_if< \
parameter::is_argument_pack<A0> \
, detail::_enabler \
>::type \
) \
{ \
return find_accumulator<Feature>(acc).result( \
( \
boost::accumulators::accumulator = acc \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a) \
) \
); \
} \
template< \
typename Feature \
, typename AccumulatorSet \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \
> \
typename mpl::apply<AccumulatorSet, Feature>::type::result_type \
extract_result( \
AccumulatorSet const &acc \
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) \
, typename boost::disable_if< \
parameter::is_argument_pack<A0> \
, detail::_enabler \
>::type \
) \
{ \
return find_accumulator<Feature>(acc).result(( \
boost::accumulators::accumulator = acc \
, boost::accumulators::sample = BOOST_PP_ENUM_PARAMS_Z(z, n, a) \
)); \
}
BOOST_PP_REPEAT_FROM_TO(
1
, BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS)
, BOOST_ACCUMULATORS_EXTRACT_RESULT_FUN
, _
)
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,333 @@
///////////////////////////////////////////////////////////////////////////////
// droppable_accumulator.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_DROPPABLE_ACCUMULATOR_HPP_EAN_13_12_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_DROPPABLE_ACCUMULATOR_HPP_EAN_13_12_2005
#include <new>
#include <boost/assert.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/aligned_storage.hpp>
#include <boost/accumulators/framework/depends_on.hpp> // for feature_of
#include <boost/accumulators/framework/parameters/accumulator.hpp> // for accumulator
namespace boost { namespace accumulators
{
template<typename Accumulator>
struct droppable_accumulator;
namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// add_ref_visitor
// a fusion function object for add_ref'ing accumulators
template<typename Args>
struct add_ref_visitor
{
explicit add_ref_visitor(Args const &args)
: args_(args)
{
}
add_ref_visitor(add_ref_visitor const &other)
: args_(other.args_)
{
}
template<typename Accumulator>
void operator ()(Accumulator &acc) const
{
typedef typename Accumulator::feature_tag::dependencies dependencies;
acc.add_ref(this->args_);
// Also add_ref accumulators that this feature depends on
this->args_[accumulator].template
visit_if<detail::contains_feature_of_<dependencies> >(
*this
);
}
private:
BOOST_DELETED_FUNCTION(add_ref_visitor &operator =(add_ref_visitor const &))
Args const &args_;
};
template<typename Args>
add_ref_visitor<Args> make_add_ref_visitor(Args const &args)
{
return add_ref_visitor<Args>(args);
}
///////////////////////////////////////////////////////////////////////////////
// drop_visitor
// a fusion function object for dropping accumulators
template<typename Args>
struct drop_visitor
{
explicit drop_visitor(Args const &args)
: args_(args)
{
}
template<typename Accumulator>
void operator ()(Accumulator &acc) const
{
if(typename Accumulator::is_droppable())
{
typedef typename Accumulator::feature_tag::dependencies dependencies;
acc.drop(this->args_);
// Also drop accumulators that this feature depends on
this->args_[accumulator].template
visit_if<detail::contains_feature_of_<dependencies> >(
*this
);
}
}
private:
BOOST_DELETED_FUNCTION(drop_visitor &operator =(drop_visitor const &))
Args const &args_;
};
template<typename Args>
drop_visitor<Args> make_drop_visitor(Args const &args)
{
return drop_visitor<Args>(args);
}
}
//////////////////////////////////////////////////////////////////////////
// droppable_accumulator_base
template<typename Accumulator>
struct droppable_accumulator_base
: Accumulator
{
typedef droppable_accumulator_base base;
typedef mpl::true_ is_droppable;
typedef typename Accumulator::result_type result_type;
template<typename Args>
droppable_accumulator_base(Args const &args)
: Accumulator(args)
, ref_count_(0)
{
}
droppable_accumulator_base(droppable_accumulator_base const &that)
: Accumulator(*static_cast<Accumulator const *>(&that))
, ref_count_(that.ref_count_)
{
}
template<typename Args>
void operator ()(Args const &args)
{
if(!this->is_dropped())
{
this->Accumulator::operator ()(args);
}
}
template<typename Args>
void add_ref(Args const &)
{
++this->ref_count_;
}
template<typename Args>
void drop(Args const &args)
{
BOOST_ASSERT(0 < this->ref_count_);
if(1 == this->ref_count_)
{
static_cast<droppable_accumulator<Accumulator> *>(this)->on_drop(args);
}
--this->ref_count_;
}
bool is_dropped() const
{
return 0 == this->ref_count_;
}
private:
int ref_count_;
};
//////////////////////////////////////////////////////////////////////////
// droppable_accumulator
// this can be specialized for any type that needs special handling
template<typename Accumulator>
struct droppable_accumulator
: droppable_accumulator_base<Accumulator>
{
template<typename Args>
droppable_accumulator(Args const &args)
: droppable_accumulator::base(args)
{
}
droppable_accumulator(droppable_accumulator const &that)
: droppable_accumulator::base(*static_cast<typename droppable_accumulator::base const *>(&that))
{
}
};
//////////////////////////////////////////////////////////////////////////
// with_cached_result
template<typename Accumulator>
struct with_cached_result
: Accumulator
{
typedef typename Accumulator::result_type result_type;
template<typename Args>
with_cached_result(Args const &args)
: Accumulator(args)
, cache()
{
}
with_cached_result(with_cached_result const &that)
: Accumulator(*static_cast<Accumulator const *>(&that))
, cache()
{
if(that.has_result())
{
this->set(that.get());
}
}
~with_cached_result()
{
// Since this is a base class of droppable_accumulator_base,
// this destructor is called before any of droppable_accumulator_base's
// members get cleaned up, including is_dropped, so the following
// call to has_result() is valid.
if(this->has_result())
{
this->get().~result_type();
}
}
template<typename Args>
void on_drop(Args const &args)
{
// cache the result at the point this calculation was dropped
BOOST_ASSERT(!this->has_result());
this->set(this->Accumulator::result(args));
}
template<typename Args>
result_type result(Args const &args) const
{
return this->has_result() ? this->get() : this->Accumulator::result(args);
}
private:
BOOST_DELETED_FUNCTION(with_cached_result &operator =(with_cached_result const &))
void set(result_type const &r)
{
::new(this->cache.address()) result_type(r);
}
result_type const &get() const
{
return *static_cast<result_type const *>(this->cache.address());
}
bool has_result() const
{
typedef with_cached_result<Accumulator> this_type;
typedef droppable_accumulator_base<this_type> derived_type;
return static_cast<derived_type const *>(this)->is_dropped();
}
aligned_storage<sizeof(result_type)> cache;
};
namespace tag
{
template<typename Feature>
struct as_droppable
{
typedef droppable<Feature> type;
};
template<typename Feature>
struct as_droppable<droppable<Feature> >
{
typedef droppable<Feature> type;
};
//////////////////////////////////////////////////////////////////////////
// droppable
template<typename Feature>
struct droppable
: as_feature<Feature>::type
{
typedef typename as_feature<Feature>::type feature_type;
typedef typename feature_type::dependencies tmp_dependencies_;
typedef
typename mpl::transform<
typename feature_type::dependencies
, as_droppable<mpl::_1>
>::type
dependencies;
struct impl
{
template<typename Sample, typename Weight>
struct apply
{
typedef
droppable_accumulator<
typename mpl::apply2<typename feature_type::impl, Sample, Weight>::type
>
type;
};
};
};
}
// make droppable<tag::feature(modifier)> work
template<typename Feature>
struct as_feature<tag::droppable<Feature> >
{
typedef tag::droppable<typename as_feature<Feature>::type> type;
};
// make droppable<tag::mean> work with non-void weights (should become
// droppable<tag::weighted_mean>
template<typename Feature>
struct as_weighted_feature<tag::droppable<Feature> >
{
typedef tag::droppable<typename as_weighted_feature<Feature>::type> type;
};
// for the purposes of feature-based dependency resolution,
// droppable<Foo> provides the same feature as Foo
template<typename Feature>
struct feature_of<tag::droppable<Feature> >
: feature_of<Feature>
{
};
// Note: Usually, the extractor is pulled into the accumulators namespace with
// a using directive, not the tag. But the droppable<> feature doesn't have an
// extractor, so we can put the droppable tag in the accumulators namespace
// without fear of a name conflict.
using tag::droppable;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,108 @@
///////////////////////////////////////////////////////////////////////////////
// external_accumulator.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_EXTERNAL_ACCUMULATOR_HPP_EAN_01_12_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_EXTERNAL_ACCUMULATOR_HPP_EAN_01_12_2005
#include <boost/mpl/placeholders.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/depends_on.hpp> // for feature_tag
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/accumulators/reference_accumulator.hpp>
namespace boost { namespace accumulators { namespace impl
{
//////////////////////////////////////////////////////////////////////////
// external_impl
/// INTERNAL ONLY
///
template<typename Accumulator, typename Tag>
struct external_impl
: accumulator_base
{
typedef typename Accumulator::result_type result_type;
typedef typename detail::feature_tag<Accumulator>::type feature_tag;
external_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
return this->extract_(args, args[parameter::keyword<Tag>::instance | 0]);
}
private:
template<typename Args>
static result_type extract_(Args const &args, int)
{
// No named parameter passed to the extractor. Maybe the external
// feature is held by reference<>.
extractor<feature_tag> extract;
return extract(accumulators::reference_tag<Tag>(args));
}
template<typename Args, typename AccumulatorSet>
static result_type extract_(Args const &, AccumulatorSet const &acc)
{
// OK, a named parameter for this external feature was passed to the
// extractor, so use that.
extractor<feature_tag> extract;
return extract(acc);
}
};
} // namespace impl
namespace tag
{
//////////////////////////////////////////////////////////////////////////
// external
template<typename Feature, typename Tag, typename AccumulatorSet>
struct external
: depends_on<reference<AccumulatorSet, Tag> >
{
typedef
accumulators::impl::external_impl<
detail::to_accumulator<Feature, mpl::_1, mpl::_2>
, Tag
>
impl;
};
template<typename Feature, typename Tag>
struct external<Feature, Tag, void>
: depends_on<>
{
typedef
accumulators::impl::external_impl<
detail::to_accumulator<Feature, mpl::_1, mpl::_2>
, Tag
>
impl;
};
}
// for the purposes of feature-based dependency resolution,
// external_accumulator<Feature, Tag> provides the same feature as Feature
template<typename Feature, typename Tag, typename AccumulatorSet>
struct feature_of<tag::external<Feature, Tag, AccumulatorSet> >
: feature_of<Feature>
{
};
// Note: Usually, the extractor is pulled into the accumulators namespace with
// a using directive, not the tag. But the external<> feature doesn't have an
// extractor, so we can put the external tag in the accumulators namespace
// without fear of a name conflict.
using tag::external;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,89 @@
///////////////////////////////////////////////////////////////////////////////
// reference_accumulator.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_REFERENCE_ACCUMULATOR_HPP_EAN_03_23_2006
#define BOOST_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_REFERENCE_ACCUMULATOR_HPP_EAN_03_23_2006
#include <boost/ref.hpp>
#include <boost/mpl/always.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/accumulators/framework/depends_on.hpp> // for feature_tag
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
//////////////////////////////////////////////////////////////////////////
// reference_accumulator_impl
//
template<typename Referent, typename Tag>
struct reference_accumulator_impl
: accumulator_base
{
typedef Referent &result_type;
template<typename Args>
reference_accumulator_impl(Args const &args)
: ref(args[parameter::keyword<Tag>::instance])
{
}
result_type result(dont_care) const
{
return this->ref;
}
private:
reference_wrapper<Referent> ref;
};
} // namespace impl
namespace tag
{
//////////////////////////////////////////////////////////////////////////
// reference_tag
template<typename Tag>
struct reference_tag
{
};
//////////////////////////////////////////////////////////////////////////
// reference
template<typename Referent, typename Tag>
struct reference
: depends_on<>
{
/// INTERNAL ONLY
///
typedef mpl::always<accumulators::impl::reference_accumulator_impl<Referent, Tag> > impl;
};
}
namespace extract
{
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, reference, (typename)(typename))
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, reference_tag, (typename))
}
using extract::reference;
using extract::reference_tag;
// Map all reference<V,T> features to reference_tag<T> so
// that references can be extracted using reference_tag<T>
// without specifying the referent type.
template<typename ValueType, typename Tag>
struct feature_of<tag::reference<ValueType, Tag> >
: feature_of<tag::reference_tag<Tag> >
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,89 @@
///////////////////////////////////////////////////////////////////////////////
// value_accumulator.hpp
//
// Copyright 2005 Eric Niebler, Daniel Egloff. 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_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_VALUE_ACCUMULATOR_HPP_EAN_03_23_2006
#define BOOST_ACCUMULATORS_FRAMEWORK_ACCUMULATORS_VALUE_ACCUMULATOR_HPP_EAN_03_23_2006
#include <boost/mpl/always.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/accumulators/framework/depends_on.hpp> // for feature_tag
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
//////////////////////////////////////////////////////////////////////////
// value_accumulator_impl
template<typename ValueType, typename Tag>
struct value_accumulator_impl
: accumulator_base
{
typedef ValueType result_type;
template<typename Args>
value_accumulator_impl(Args const &args)
: val(args[parameter::keyword<Tag>::instance])
{
}
result_type result(dont_care) const
{
return this->val;
}
private:
ValueType val;
};
} // namespace impl
namespace tag
{
//////////////////////////////////////////////////////////////////////////
// value_tag
template<typename Tag>
struct value_tag
{
};
//////////////////////////////////////////////////////////////////////////
// value
template<typename ValueType, typename Tag>
struct value
: depends_on<>
{
/// INTERNAL ONLY
///
typedef mpl::always<accumulators::impl::value_accumulator_impl<ValueType, Tag> > impl;
};
}
namespace extract
{
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, value, (typename)(typename))
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, value_tag, (typename))
}
using extract::value;
using extract::value_tag;
// Map all value<V,T> features to value_tag<T> so
// that values can be extracted using value_tag<T>
// without specifying the value type.
template<typename ValueType, typename Tag>
struct feature_of<tag::value<ValueType, Tag> >
: feature_of<tag::value_tag<Tag> >
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,461 @@
///////////////////////////////////////////////////////////////////////////////
// depends_on.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_DEPENDS_ON_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_DEPENDS_ON_HPP_EAN_28_10_2005
#include <boost/version.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/map.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/sort.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/remove.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/equal_to.hpp>
#include <boost/mpl/contains.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <boost/mpl/transform_view.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
#include <boost/fusion/include/next.hpp>
#include <boost/fusion/include/equal_to.hpp>
#include <boost/fusion/include/value_of.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/end.hpp>
#include <boost/fusion/include/begin.hpp>
#include <boost/fusion/include/cons.hpp>
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////
// as_feature
template<typename Feature>
struct as_feature
{
typedef Feature type;
};
///////////////////////////////////////////////////////////////////////////
// weighted_feature
template<typename Feature>
struct as_weighted_feature
{
typedef Feature type;
};
///////////////////////////////////////////////////////////////////////////
// feature_of
template<typename Feature>
struct feature_of
{
typedef Feature type;
};
namespace detail
{
///////////////////////////////////////////////////////////////////////////
// feature_tag
template<typename Accumulator>
struct feature_tag
{
typedef typename Accumulator::feature_tag type;
};
template<typename Feature>
struct undroppable
{
typedef Feature type;
};
template<typename Feature>
struct undroppable<tag::droppable<Feature> >
{
typedef Feature type;
};
// For the purpose of determining whether one feature depends on another,
// disregard whether the feature is droppable or not.
template<typename A, typename B>
struct is_dependent_on
: is_base_and_derived<
typename feature_of<typename undroppable<B>::type>::type
, typename undroppable<A>::type
>
{};
template<typename Feature>
struct dependencies_of
{
typedef typename Feature::dependencies type;
};
// Should use mpl::insert_range, but doesn't seem to work with mpl sets
template<typename Set, typename Range>
struct set_insert_range
: mpl::fold<
Range
, Set
, mpl::insert<mpl::_1, mpl::_2>
>
{};
template<typename Features>
struct collect_abstract_features
: mpl::fold<
Features
, mpl::set0<>
, set_insert_range<
mpl::insert<mpl::_1, feature_of<mpl::_2> >
, collect_abstract_features<dependencies_of<mpl::_2> >
>
>
{};
template<typename Features>
struct depends_on_base
: mpl::inherit_linearly<
typename mpl::sort<
typename mpl::copy<
typename collect_abstract_features<Features>::type
, mpl::back_inserter<mpl::vector0<> >
>::type
, is_dependent_on<mpl::_1, mpl::_2>
>::type
// Don't inherit multiply from a feature
, mpl::if_<
is_dependent_on<mpl::_1, mpl::_2>
, mpl::_1
, mpl::inherit<mpl::_1, mpl::_2>
>
>::type
{
};
}
///////////////////////////////////////////////////////////////////////////
/// depends_on
template<BOOST_PP_ENUM_PARAMS(BOOST_ACCUMULATORS_MAX_FEATURES, typename Feature)>
struct depends_on
: detail::depends_on_base<
typename mpl::transform<
mpl::vector<BOOST_PP_ENUM_PARAMS(BOOST_ACCUMULATORS_MAX_FEATURES, Feature)>
, as_feature<mpl::_1>
>::type
>
{
typedef mpl::false_ is_weight_accumulator;
typedef
typename mpl::transform<
mpl::vector<BOOST_PP_ENUM_PARAMS(BOOST_ACCUMULATORS_MAX_FEATURES, Feature)>
, as_feature<mpl::_1>
>::type
dependencies;
};
namespace detail
{
template<typename Feature>
struct matches_feature
{
template<typename Accumulator>
struct apply
: is_same<
typename feature_of<typename as_feature<Feature>::type>::type
, typename feature_of<typename as_feature<typename feature_tag<Accumulator>::type>::type>::type
>
{};
};
template<typename Features, typename Accumulator>
struct contains_feature_of
{
typedef
mpl::transform_view<Features, feature_of<as_feature<mpl::_> > >
features_list;
typedef
typename feature_of<typename feature_tag<Accumulator>::type>::type
the_feature;
typedef
typename mpl::contains<features_list, the_feature>::type
type;
};
// This is to work around a bug in early versions of Fusion which caused
// a compile error if contains_feature_of<List, mpl::_> is used as a
// predicate to fusion::find_if
template<typename Features>
struct contains_feature_of_
{
template<typename Accumulator>
struct apply
: contains_feature_of<Features, Accumulator>
{};
};
template<
typename First
, typename Last
, bool is_empty = fusion::result_of::equal_to<First, Last>::value
>
struct build_acc_list;
template<typename First, typename Last>
struct build_acc_list<First, Last, true>
{
typedef fusion::nil_ type;
template<typename Args>
static fusion::nil_
call(Args const &, First const&, Last const&)
{
return fusion::nil_();
}
};
template<typename First, typename Last>
struct build_acc_list<First, Last, false>
{
typedef
build_acc_list<typename fusion::result_of::next<First>::type, Last>
next_build_acc_list;
typedef fusion::cons<
typename fusion::result_of::value_of<First>::type
, typename next_build_acc_list::type>
type;
template<typename Args>
static type
call(Args const &args, First const& f, Last const& l)
{
return type(args, next_build_acc_list::call(args, fusion::next(f), l));
}
};
namespace meta
{
template<typename Sequence>
struct make_acc_list
: build_acc_list<
typename fusion::result_of::begin<Sequence>::type
, typename fusion::result_of::end<Sequence>::type
>
{};
}
template<typename Sequence, typename Args>
typename meta::make_acc_list<Sequence>::type
make_acc_list(Sequence &seq, Args const &args)
{
return meta::make_acc_list<Sequence>::call(args, fusion::begin(seq), fusion::end(seq));
}
template<typename Sequence, typename Args>
typename meta::make_acc_list<Sequence>::type
make_acc_list(Sequence const &seq, Args const &args)
{
return meta::make_acc_list<Sequence const>::call(args, fusion::begin(seq), fusion::end(seq));
}
///////////////////////////////////////////////////////////////////////////
// checked_as_weighted_feature
template<typename Feature>
struct checked_as_weighted_feature
{
typedef typename as_feature<Feature>::type feature_type;
typedef typename as_weighted_feature<feature_type>::type type;
// weighted and non-weighted flavors should provide the same feature.
BOOST_MPL_ASSERT((
is_same<
typename feature_of<feature_type>::type
, typename feature_of<type>::type
>
));
};
///////////////////////////////////////////////////////////////////////////
// as_feature_list
template<typename Features, typename Weight>
struct as_feature_list
: mpl::transform_view<Features, checked_as_weighted_feature<mpl::_1> >
{
};
template<typename Features>
struct as_feature_list<Features, void>
: mpl::transform_view<Features, as_feature<mpl::_1> >
{
};
///////////////////////////////////////////////////////////////////////////
// accumulator_wrapper
template<typename Accumulator, typename Feature>
struct accumulator_wrapper
: Accumulator
{
typedef Feature feature_tag;
accumulator_wrapper(accumulator_wrapper const &that)
: Accumulator(*static_cast<Accumulator const *>(&that))
{
}
accumulator_wrapper& operator=(accumulator_wrapper const &that)
{
*static_cast<Accumulator *>(this) = *static_cast<Accumulator const *>(&that);
return *this;
}
template<typename Args>
accumulator_wrapper(Args const &args)
: Accumulator(args)
{
}
};
///////////////////////////////////////////////////////////////////////////
// to_accumulator
template<typename Feature, typename Sample, typename Weight>
struct to_accumulator
{
typedef
accumulator_wrapper<
typename mpl::apply2<typename Feature::impl, Sample, Weight>::type
, Feature
>
type;
};
template<typename Feature, typename Sample, typename Weight, typename Tag, typename AccumulatorSet>
struct to_accumulator<Feature, Sample, tag::external<Weight, Tag, AccumulatorSet> >
{
BOOST_MPL_ASSERT((is_same<Tag, void>));
BOOST_MPL_ASSERT((is_same<AccumulatorSet, void>));
typedef
accumulator_wrapper<
typename mpl::apply2<typename Feature::impl, Sample, Weight>::type
, Feature
>
accumulator_type;
typedef
typename mpl::if_<
typename Feature::is_weight_accumulator
, accumulator_wrapper<impl::external_impl<accumulator_type, tag::weights>, Feature>
, accumulator_type
>::type
type;
};
// BUGBUG work around an MPL bug wrt map insertion
template<typename FeatureMap, typename Feature>
struct insert_feature
: mpl::eval_if<
mpl::has_key<FeatureMap, typename feature_of<Feature>::type>
, mpl::identity<FeatureMap>
, mpl::insert<FeatureMap, mpl::pair<typename feature_of<Feature>::type, Feature> >
>
{
};
template<typename FeatureMap, typename Feature, typename Weight>
struct insert_dependencies
: mpl::fold<
as_feature_list<typename Feature::dependencies, Weight>
, FeatureMap
, insert_dependencies<
insert_feature<mpl::_1, mpl::_2>
, mpl::_2
, Weight
>
>
{
};
template<typename FeatureMap, typename Features, typename Weight>
struct insert_sequence
: mpl::fold< // BUGBUG should use insert_range, but doesn't seem to work for maps
as_feature_list<Features, Weight>
, FeatureMap
, insert_feature<mpl::_1, mpl::_2>
>
{
};
template<typename Features, typename Sample, typename Weight>
struct make_accumulator_tuple
{
typedef
typename mpl::fold<
as_feature_list<Features, Weight>
, mpl::map0<>
, mpl::if_<
mpl::is_sequence<mpl::_2>
, insert_sequence<mpl::_1, mpl::_2, Weight>
, insert_feature<mpl::_1, mpl::_2>
>
>::type
feature_map;
// for each element in the map, add its dependencies also
typedef
typename mpl::fold<
feature_map
, feature_map
, insert_dependencies<mpl::_1, mpl::second<mpl::_2>, Weight>
>::type
feature_map_with_dependencies;
// turn the map into a vector so we can sort it
typedef
typename mpl::insert_range<
mpl::vector<>
, mpl::end<mpl::vector<> >::type
, mpl::transform_view<feature_map_with_dependencies, mpl::second<mpl::_1> >
>::type
feature_vector_with_dependencies;
// sort the features according to which is derived from which
typedef
typename mpl::sort<
feature_vector_with_dependencies
, is_dependent_on<mpl::_2, mpl::_1>
>::type
sorted_feature_vector;
// From the vector of features, construct a vector of accumulators
typedef
typename mpl::transform<
sorted_feature_vector
, to_accumulator<mpl::_1, Sample, Weight>
>::type
type;
};
} // namespace detail
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,27 @@
///////////////////////////////////////////////////////////////////////////////
// external.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_EXTERNAL_HPP_EAN_01_12_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_EXTERNAL_HPP_EAN_01_12_2005
#include <boost/mpl/apply.hpp>
#include <boost/accumulators/framework/accumulators/external_accumulator.hpp>
//namespace boost { namespace accumulators
//{
//
/////////////////////////////////////////////////////////////////////////////////
//// external
////
//template<typename Type>
//struct external
//{
//};
//
//}} // namespace boost::accumulators
#endif
@@ -0,0 +1,248 @@
///////////////////////////////////////////////////////////////////////////////
// extractor.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_EXTRACTOR_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_EXTRACTOR_HPP_EAN_28_10_2005
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/tuple/rem.hpp>
#include <boost/preprocessor/array/size.hpp>
#include <boost/preprocessor/array/data.hpp>
#include <boost/preprocessor/array/elem.hpp>
#include <boost/preprocessor/seq/to_array.hpp>
#include <boost/preprocessor/seq/transform.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/parameter/binding.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
#include <boost/accumulators/framework/parameters/accumulator.hpp>
namespace boost { namespace accumulators
{
namespace detail
{
template<typename AccumulatorSet, typename Feature>
struct accumulator_set_result
{
typedef typename as_feature<Feature>::type feature_type;
typedef typename mpl::apply<
typename boost::remove_const<
typename boost::remove_reference<AccumulatorSet>::type
>::type
, feature_type
>::type::result_type type;
};
template<typename Args, typename Feature>
struct argument_pack_result
: accumulator_set_result<
typename boost::remove_reference<
typename parameter::binding<
typename boost::remove_const<
typename boost::remove_reference<Args>::type
>::type
, tag::accumulator
>::type
>::type
, Feature
>
{
};
template<typename A, typename Feature>
struct extractor_result
: mpl::eval_if<
detail::is_accumulator_set<A>
, accumulator_set_result<A, Feature>
, argument_pack_result<A, Feature>
>
{
};
template<typename Feature, typename AccumulatorSet>
typename extractor_result<AccumulatorSet, Feature>::type
do_extract(AccumulatorSet const &acc, mpl::true_)
{
typedef typename as_feature<Feature>::type feature_type;
return extract_result<feature_type>(acc);
}
template<typename Feature, typename Args>
typename extractor_result<Args, Feature>::type
do_extract(Args const &args, mpl::false_)
{
typedef typename as_feature<Feature>::type feature_type;
return find_accumulator<feature_type>(args[accumulator]).result(args);
}
} // namespace detail
///////////////////////////////////////////////////////////////////////////////
/// Extracts the result associated with Feature from the specified accumulator_set.
template<typename Feature>
struct extractor
{
typedef extractor<Feature> this_type;
/// The result meta-function for determining the return type of the extractor
template<typename F>
struct result;
template<typename A1>
struct result<this_type(A1)>
: detail::extractor_result<A1, Feature>
{
};
/// Extract the result associated with Feature from the accumulator set
/// \param acc The accumulator set object from which to extract the result
template<typename Arg1>
typename detail::extractor_result<Arg1, Feature>::type
operator ()(Arg1 const &arg1) const
{
// Arg1 could be an accumulator_set or an argument pack containing
// an accumulator_set. Dispatch accordingly.
return detail::do_extract<Feature>(arg1, detail::is_accumulator_set<Arg1>());
}
/// \overload
///
/// \param a1 Optional named parameter to be passed to the accumulator's result() function.
template<typename AccumulatorSet, typename A1>
typename detail::extractor_result<AccumulatorSet, Feature>::type
operator ()(AccumulatorSet const &acc, A1 const &a1) const
{
BOOST_MPL_ASSERT((detail::is_accumulator_set<AccumulatorSet>));
typedef typename as_feature<Feature>::type feature_type;
return extract_result<feature_type>(acc, a1);
}
// ... other overloads generated by Boost.Preprocessor:
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_EXTRACTOR_FUN_OP(z, n, _) \
template<BOOST_PP_ENUM_PARAMS_Z(z, n, typename A)> \
struct result<this_type(BOOST_PP_ENUM_PARAMS_Z(z, n, A))> \
: detail::extractor_result<A1, Feature> \
{}; \
template< \
typename AccumulatorSet \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \
> \
typename detail::extractor_result<AccumulatorSet, Feature>::type \
operator ()( \
AccumulatorSet const &acc \
BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) \
) const \
{ \
BOOST_MPL_ASSERT((detail::is_accumulator_set<AccumulatorSet>)); \
typedef typename as_feature<Feature>::type feature_type; \
return extract_result<feature_type>(acc BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a));\
}
BOOST_PP_REPEAT_FROM_TO(
2
, BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS)
, BOOST_ACCUMULATORS_EXTRACTOR_FUN_OP
, _
)
#undef BOOST_ACCUMULATORS_EXTRACTOR_FUN_OP
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// \overload
///
template<typename AccumulatorSet, typename A1, typename A2, ...>
typename detail::extractor_result<AccumulatorSet, Feature>::type
operator ()(AccumulatorSet const &acc, A1 const &a1, A2 const &a2, ...);
#endif
};
}} // namespace boost::accumulators
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_ARRAY_REM(Array) \
BOOST_PP_TUPLE_REM_CTOR(BOOST_PP_ARRAY_SIZE(Array), BOOST_PP_ARRAY_DATA(Array))
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_SEQ_REM(Seq) \
BOOST_ACCUMULATORS_ARRAY_REM(BOOST_PP_SEQ_TO_ARRAY(Seq))
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_ARGS_OP(s, data, elem) \
T ## s
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_PARAMS_OP(s, data, elem) \
elem T ## s
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) \
Tag::Feature< \
BOOST_ACCUMULATORS_SEQ_REM( \
BOOST_PP_SEQ_TRANSFORM(BOOST_ACCUMULATORS_ARGS_OP, ~, ParamsSeq) \
) \
>
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN_IMPL(z, n, Tag, Feature, ParamsSeq) \
template< \
BOOST_ACCUMULATORS_SEQ_REM( \
BOOST_PP_SEQ_TRANSFORM(BOOST_ACCUMULATORS_PARAMS_OP, ~, ParamsSeq) \
) \
, typename Arg1 \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, typename A) \
> \
typename boost::accumulators::detail::extractor_result< \
Arg1 \
, BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) \
>::type \
Feature(Arg1 const &arg1 BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, n, A, const &a) ) \
{ \
typedef BOOST_ACCUMULATORS_MAKE_FEATURE(Tag, Feature, ParamsSeq) feature_type; \
return boost::accumulators::extractor<feature_type>()( \
arg1 BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, a)); \
}
/// INTERNAL ONLY
///
#define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN(z, n, _) \
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN_IMPL( \
z \
, n \
, BOOST_PP_ARRAY_ELEM(0, _) \
, BOOST_PP_ARRAY_ELEM(1, _) \
, BOOST_PP_ARRAY_ELEM(2, _) \
)
#define BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(Tag, Feature, ParamSeq) \
BOOST_PP_REPEAT( \
BOOST_PP_INC(BOOST_ACCUMULATORS_MAX_ARGS) \
, BOOST_ACCUMULATORS_DEFINE_EXTRACTOR_FUN \
, (3, (Tag, Feature, ParamSeq)) \
)
#endif
@@ -0,0 +1,29 @@
///////////////////////////////////////////////////////////////////////////////
// features.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_STATS_HPP_EAN_08_12_2005
#define BOOST_ACCUMULATORS_STATISTICS_STATS_HPP_EAN_08_12_2005
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////////
// features
//
template<BOOST_PP_ENUM_PARAMS(BOOST_ACCUMULATORS_MAX_FEATURES, typename Feature)>
struct features
: mpl::vector<BOOST_PP_ENUM_PARAMS(BOOST_ACCUMULATORS_MAX_FEATURES, Feature)>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,22 @@
///////////////////////////////////////////////////////////////////////////////
// accumulator.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_PARAMETERS_ACCUMULATOR_HPP_EAN_31_10_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_PARAMETERS_ACCUMULATOR_HPP_EAN_31_10_2005
#include <boost/parameter/name.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
namespace boost { namespace accumulators
{
BOOST_PARAMETER_NAME((accumulator, tag) accumulator)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(accumulator)
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,22 @@
///////////////////////////////////////////////////////////////////////////////
// sample.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_PARAMETERS_SAMPLE_HPP_EAN_31_10_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_PARAMETERS_SAMPLE_HPP_EAN_31_10_2005
#include <boost/parameter/name.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
namespace boost { namespace accumulators
{
BOOST_PARAMETER_NAME((sample, tag) sample)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(sample)
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,23 @@
///////////////////////////////////////////////////////////////////////////////
// weight.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_PARAMETERS_WEIGHT_HPP_EAN_31_10_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_PARAMETERS_WEIGHT_HPP_EAN_31_10_2005
#include <boost/parameter/name.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
namespace boost { namespace accumulators
{
// The weight of a single sample
BOOST_PARAMETER_NAME((weight, tag) weight)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weight)
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,23 @@
///////////////////////////////////////////////////////////////////////////////
// weights.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_FRAMEWORK_PARAMETERS_WEIGHTS_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_FRAMEWORK_PARAMETERS_WEIGHTS_HPP_EAN_28_10_2005
#include <boost/parameter/name.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
namespace boost { namespace accumulators
{
// The weight accumulator
BOOST_PARAMETER_NAME((weights, tag) weights)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weights)
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,75 @@
// Copyright David Abrahams 2006. 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_DETAIL_FUNCTION1_DWA200655_HPP
# define BOOST_DETAIL_FUNCTION1_DWA200655_HPP
# include <boost/concept_check.hpp>
# include <boost/type_traits/remove_reference.hpp>
# include <boost/type_traits/add_const.hpp>
# include <boost/mpl/apply.hpp>
namespace boost { namespace detail {
// A utility for creating unary function objects that play nicely with
// boost::result_of and that handle the forwarding problem.
//
// mpl::apply<F, A0>::type is expected to be a stateless function
// object that accepts an argument of type A0&. It is also expected
// to have a nested ::result_type identical to its return type.
template<typename F>
struct function1
{
template<typename Signature>
struct result
{};
template<typename This, typename A0>
struct result<This(A0)>
{
// How adding const to arguments handles rvalues.
//
// if A0 is arg0 is represents actual argument
// -------- ------- --------------------------
// T const & T const const T lvalue
// T & T non-const T lvalue
// T const T const const T rvalue
// T T const non-const T rvalue
typedef typename remove_reference<
typename add_const< A0 >::type
>::type arg0;
typedef typename mpl::apply1<F, arg0>::type impl;
typedef typename impl::result_type type;
};
// Handles mutable lvalues
template<typename A0>
typename result<function1(A0 &)>::type
operator ()(A0 &a0) const
{
typedef typename result<function1(A0 &)>::impl impl;
typedef typename result<function1(A0 &)>::type type;
typedef A0 &arg0;
BOOST_CONCEPT_ASSERT((UnaryFunction<impl, type, arg0>));
//boost::function_requires<UnaryFunctionConcept<impl, type, arg0> >();
return impl()(a0);
}
// Handles const lvalues and all rvalues
template<typename A0>
typename result<function1(A0 const &)>::type
operator ()(A0 const &a0) const
{
typedef typename result<function1(A0 const &)>::impl impl;
typedef typename result<function1(A0 const &)>::type type;
typedef A0 const &arg0;
BOOST_CONCEPT_ASSERT((UnaryFunction<impl, type, arg0>));
//boost::function_requires<UnaryFunctionConcept<impl, type, arg0> >();
return impl()(a0);
}
};
}} // namespace boost::detail
#endif // BOOST_DETAIL_FUNCTION1_DWA200655_HPP
@@ -0,0 +1,10 @@
// Copyright David Abrahams 2006. 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_DETAIL_FUNCTION2_DWA200655_HPP
# define BOOST_DETAIL_FUNCTION2_DWA200655_HPP
# define args (2)
# include <boost/accumulators/numeric/detail/function_n.hpp>
#endif // BOOST_DETAIL_FUNCTION2_DWA200655_HPP
@@ -0,0 +1,10 @@
// Copyright David Abrahams 2006. 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_DETAIL_FUNCTION3_DWA2006514_HPP
# define BOOST_DETAIL_FUNCTION3_DWA2006514_HPP
# define args (3)
# include <boost/accumulators/numeric/detail/function_n.hpp>
#endif // BOOST_DETAIL_FUNCTION3_DWA2006514_HPP
@@ -0,0 +1,10 @@
// Copyright David Abrahams 2006. 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_DETAIL_FUNCTION4_DWA2006514_HPP
# define BOOST_DETAIL_FUNCTION4_DWA2006514_HPP
# define args (4)
# include <boost/accumulators/numeric/detail/function_n.hpp>
#endif // BOOST_DETAIL_FUNCTION4_DWA2006514_HPP
@@ -0,0 +1,148 @@
// Copyright David Abrahams 2006. 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)
//
// #include guards intentionally disabled.
// #ifndef BOOST_DETAIL_FUNCTION_N_DWA2006514_HPP
// # define BOOST_DETAIL_FUNCTION_N_DWA2006514_HPP
#include <boost/mpl/void.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/preprocessor/control/if.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/seq/fold_left.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/seq/for_each_product.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
namespace boost { namespace detail {
# define BOOST_DETAIL_default_arg(z, n, _) \
typedef mpl::void_ BOOST_PP_CAT(arg, n);
# define BOOST_DETAIL_function_arg(z, n, _) \
typedef typename remove_reference< \
typename add_const< BOOST_PP_CAT(A, n) >::type \
>::type BOOST_PP_CAT(arg, n);
#define BOOST_DETAIL_cat_arg_counts(s, state, n) \
BOOST_PP_IF( \
n \
, BOOST_PP_CAT(state, BOOST_PP_CAT(_, n)) \
, state \
) \
/**/
#define function_name \
BOOST_PP_SEQ_FOLD_LEFT( \
BOOST_DETAIL_cat_arg_counts \
, BOOST_PP_CAT(function, BOOST_PP_SEQ_HEAD(args)) \
, BOOST_PP_SEQ_TAIL(args)(0) \
) \
/**/
template<typename F>
struct function_name
{
BOOST_PP_REPEAT(
BOOST_MPL_LIMIT_METAFUNCTION_ARITY
, BOOST_DETAIL_default_arg
, ~
)
template<typename Signature>
struct result {};
#define BOOST_DETAIL_function_result(r, _, n) \
template<typename This BOOST_PP_ENUM_TRAILING_PARAMS(n, typename A)> \
struct result<This(BOOST_PP_ENUM_PARAMS(n, A))> \
{ \
BOOST_PP_REPEAT(n, BOOST_DETAIL_function_arg, ~) \
typedef \
typename BOOST_PP_CAT(mpl::apply, BOOST_MPL_LIMIT_METAFUNCTION_ARITY)<\
F \
BOOST_PP_ENUM_TRAILING_PARAMS( \
BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
, arg \
) \
>::type \
impl; \
typedef typename impl::result_type type; \
}; \
/**/
BOOST_PP_SEQ_FOR_EACH(BOOST_DETAIL_function_result, _, args)
# define arg_type(r, _, i, is_const) \
BOOST_PP_COMMA_IF(i) BOOST_PP_CAT(A, i) BOOST_PP_CAT(const_if, is_const) &
# define result_(r, n, constness) \
typename result< \
function_name( \
BOOST_PP_SEQ_FOR_EACH_I_R(r, arg_type, ~, constness) \
) \
> \
/**/
# define param(r, _, i, is_const) BOOST_PP_COMMA_IF(i) \
BOOST_PP_CAT(A, i) BOOST_PP_CAT(const_if, is_const) & BOOST_PP_CAT(x, i)
# define param_list(r, n, constness) \
BOOST_PP_SEQ_FOR_EACH_I_R(r, param, ~, constness)
# define call_operator(r, constness) \
template<BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(constness), typename A)> \
result_(r, BOOST_PP_SEQ_SIZE(constness), constness)::type \
operator ()( param_list(r, BOOST_PP_SEQ_SIZE(constness), constness) ) const \
{ \
typedef result_(r, BOOST_PP_SEQ_SIZE(constness), constness)::impl impl; \
return impl()(BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(constness), x)); \
} \
/**/
# define const_if0
# define const_if1 const
# define bits(z, n, _) ((0)(1))
# define gen_operator(r, _, n) \
BOOST_PP_SEQ_FOR_EACH_PRODUCT_R( \
r \
, call_operator \
, BOOST_PP_REPEAT(n, bits, ~) \
) \
/**/
BOOST_PP_SEQ_FOR_EACH(
gen_operator
, ~
, args
)
# undef bits
# undef const_if1
# undef const_if0
# undef call_operator
# undef param_list
# undef param
# undef result_
# undef default_
# undef arg_type
# undef gen_operator
# undef function_name
# undef args
};
}} // namespace boost::detail
//#endif // BOOST_DETAIL_FUNCTION_N_DWA2006514_HPP
@@ -0,0 +1,20 @@
// Copyright David Abrahams 2006. 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_DETAIL_POD_SINGLETON_DWA200655_HPP
# define BOOST_DETAIL_POD_SINGLETON_DWA200655_HPP
namespace boost { namespace detail {
template<typename T>
struct pod_singleton
{
static T instance;
};
template<typename T>
T pod_singleton<T>::instance;
}} // namespace boost::detail
#endif // BOOST_DETAIL_POD_SINGLETON_DWA200655_HPP
@@ -0,0 +1,537 @@
///////////////////////////////////////////////////////////////////////////////
/// \file functional.hpp
///
// Copyright 2005 Eric Niebler. 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_NUMERIC_FUNCTIONAL_HPP_EAN_08_12_2005
#define BOOST_NUMERIC_FUNCTIONAL_HPP_EAN_08_12_2005
#include <limits>
#include <functional>
#include <boost/static_assert.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/and.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/type_traits/is_empty.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
#include <boost/accumulators/numeric/functional_fwd.hpp>
#include <boost/accumulators/numeric/detail/function1.hpp>
#include <boost/accumulators/numeric/detail/function2.hpp>
#include <boost/accumulators/numeric/detail/pod_singleton.hpp>
#ifdef BOOST_NUMERIC_FUNCTIONAL_STD_VECTOR_SUPPORT
# include <boost/accumulators/numeric/functional/vector.hpp>
#endif
#ifdef BOOST_NUMERIC_FUNCTIONAL_STD_VALARRAY_SUPPORT
# include <boost/accumulators/numeric/functional/valarray.hpp>
#endif
#ifdef BOOST_NUMERIC_FUNCTIONAL_STD_COMPLEX_SUPPORT
# include <boost/accumulators/numeric/functional/complex.hpp>
#endif
/// INTERNAL ONLY
///
#define BOOST_NUMERIC_FUNCTIONAL_HPP_INCLUDED
#ifdef BOOST_NUMERIC_FUNCTIONAL_DOXYGEN_INVOKED
// Hack to make Doxygen show the inheritance relationships
/// INTERNAL ONLY
///
namespace std
{
/// INTERNAL ONLY
///
template<class Arg, class Ret> struct unary_function {};
/// INTERNAL ONLY
///
template<class Left, class Right, class Ret> struct binary_function {};
}
#endif
namespace boost { namespace numeric
{
namespace functional
{
/// INTERNAL ONLY
///
template<typename A0, typename A1>
struct are_integral
: mpl::and_<is_integral<A0>, is_integral<A1> >
{};
template<typename Left, typename Right>
struct left_ref
{
typedef Left &type;
};
namespace detail
{
template<typename T>
T &lvalue_of();
}
}
// TODO: handle complex weight, valarray, MTL vectors
/// INTERNAL ONLY
///
#define BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(Name, Op) \
namespace functional \
{ \
template<typename Arg> \
struct result_of_ ## Name \
{ \
BOOST_TYPEOF_NESTED_TYPEDEF_TPL( \
nested \
, Op boost::numeric::functional::detail::lvalue_of<Arg>() \
) \
typedef typename nested::type type; \
}; \
template<typename Arg, typename EnableIf> \
struct Name ## _base \
{ \
typedef typename remove_const<Arg>::type argument_type; \
typedef typename result_of_ ## Name<Arg>::type result_type; \
typename result_of_ ## Name<Arg>::type operator ()(Arg &arg) const \
{ \
return Op arg; \
} \
}; \
template<typename Arg, typename ArgTag> \
struct Name \
: Name ## _base<Arg, void> \
{}; \
} \
namespace op \
{ \
struct Name \
: boost::detail::function1<functional::Name<_, functional::tag<_> > > \
{}; \
} \
namespace \
{ \
op::Name const &Name = boost::detail::pod_singleton<op::Name>::instance; \
} \
/**/
/// INTERNAL ONLY
///
#define BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(Name, Op, RetType) \
namespace functional \
{ \
template<typename Left, typename Right, typename EnableIf> \
struct result_of_ ## Name \
{ \
RetType(Left, Op, Right) \
}; \
template<typename Left, typename Right, typename EnableIf> \
struct Name ## _base \
{ \
typedef typename remove_const<Left>::type first_argument_type; \
typedef typename remove_const<Right>::type second_argument_type; \
typedef typename result_of_ ## Name<Left, Right>::type result_type; \
typename result_of_ ## Name<Left, Right>::type \
operator ()(Left &left, Right &right) const \
{ \
return left Op right; \
} \
}; \
template<typename Left, typename Right, typename LeftTag, typename RightTag> \
struct Name \
: Name ## _base<Left, Right, void> \
{}; \
} \
namespace op \
{ \
struct Name \
: boost::detail::function2< \
functional::Name<_1, _2, functional::tag<_1>, functional::tag<_2> > \
> \
{}; \
} \
namespace \
{ \
op::Name const &Name = boost::detail::pod_singleton<op::Name>::instance; \
} \
BOOST_ACCUMULATORS_IGNORE_GLOBAL(Name) \
/**/
/// INTERNAL ONLY
///
#define BOOST_NUMERIC_FUNCTIONAL_DEDUCED(Left, Op, Right) \
BOOST_TYPEOF_NESTED_TYPEDEF_TPL( \
nested \
, boost::numeric::functional::detail::lvalue_of<Left>() Op \
boost::numeric::functional::detail::lvalue_of<Right>() \
) \
typedef typename nested::type type; \
/**/
/// INTERNAL ONLY
///
#define BOOST_NUMERIC_FUNCTIONAL_LEFT(Left, Op, Right) \
typedef Left &type; \
/**/
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(plus, +, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(minus, -, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(multiplies, *, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(divides, /, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(modulus, %, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(greater, >, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(greater_equal, >=, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(less, <, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(less_equal, <=, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(equal_to, ==, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(not_equal_to, !=, BOOST_NUMERIC_FUNCTIONAL_DEDUCED)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(assign, =, BOOST_NUMERIC_FUNCTIONAL_LEFT)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(plus_assign, +=, BOOST_NUMERIC_FUNCTIONAL_LEFT)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(minus_assign, -=, BOOST_NUMERIC_FUNCTIONAL_LEFT)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(multiplies_assign, *=, BOOST_NUMERIC_FUNCTIONAL_LEFT)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(divides_assign, /=, BOOST_NUMERIC_FUNCTIONAL_LEFT)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP(modulus_assign, %=, BOOST_NUMERIC_FUNCTIONAL_LEFT)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(unary_plus, +)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(unary_minus, -)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(complement, ~)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP(logical_not, !)
#undef BOOST_NUMERIC_FUNCTIONAL_LEFT
#undef BOOST_NUMERIC_FUNCTIONAL_DEDUCED
#undef BOOST_NUMERIC_FUNCTIONAL_DEFINE_UNARY_OP
#undef BOOST_NUMERIC_FUNCTIONAL_DEFINE_BINARY_OP
namespace functional
{
template<typename Left, typename Right, typename EnableIf>
struct min_assign_base
{
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const
{
if(numeric::less(right, left))
{
left = right;
}
}
};
template<typename Left, typename Right, typename EnableIf>
struct max_assign_base
{
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const
{
if(numeric::greater(right, left))
{
left = right;
}
}
};
template<typename Left, typename Right, typename EnableIf>
struct fdiv_base
: functional::divides<Left, Right>
{};
// partial specialization that promotes the arguments to double for
// integral division.
template<typename Left, typename Right>
struct fdiv_base<Left, Right, typename enable_if<are_integral<Left, Right> >::type>
: functional::divides<double const, double const>
{};
template<typename To, typename From, typename EnableIf>
struct promote_base
{
typedef From argument_type;
typedef To result_type;
To operator ()(From &from) const
{
return from;
}
};
template<typename ToFrom>
struct promote_base<ToFrom, ToFrom, void>
{
typedef ToFrom argument_type;
typedef ToFrom result_type;
ToFrom &operator ()(ToFrom &tofrom)
{
return tofrom;
}
};
template<typename Arg, typename EnableIf>
struct as_min_base
{
BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized);
typedef Arg argument_type;
typedef typename remove_const<Arg>::type result_type;
typename remove_const<Arg>::type operator ()(Arg &) const
{
return (std::numeric_limits<typename remove_const<Arg>::type>::min)();
}
};
template<typename Arg>
struct as_min_base<Arg, typename enable_if<is_floating_point<Arg> >::type>
{
BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized);
typedef Arg argument_type;
typedef typename remove_const<Arg>::type result_type;
typename remove_const<Arg>::type operator ()(Arg &) const
{
return -(std::numeric_limits<typename remove_const<Arg>::type>::max)();
}
};
template<typename Arg, typename EnableIf>
struct as_max_base
{
BOOST_STATIC_ASSERT(std::numeric_limits<typename remove_const<Arg>::type>::is_specialized);
typedef Arg argument_type;
typedef typename remove_const<Arg>::type result_type;
typename remove_const<Arg>::type operator ()(Arg &) const
{
return (std::numeric_limits<typename remove_const<Arg>::type>::max)();
}
};
template<typename Arg, typename EnableIf>
struct as_zero_base
{
typedef Arg argument_type;
typedef typename remove_const<Arg>::type result_type;
typename remove_const<Arg>::type operator ()(Arg &) const
{
return numeric::zero<typename remove_const<Arg>::type>::value;
}
};
template<typename Arg, typename EnableIf>
struct as_one_base
{
typedef Arg argument_type;
typedef typename remove_const<Arg>::type result_type;
typename remove_const<Arg>::type operator ()(Arg &) const
{
return numeric::one<typename remove_const<Arg>::type>::value;
}
};
template<typename To, typename From, typename ToTag, typename FromTag>
struct promote
: promote_base<To, From, void>
{};
template<typename Left, typename Right, typename LeftTag, typename RightTag>
struct min_assign
: min_assign_base<Left, Right, void>
{};
template<typename Left, typename Right, typename LeftTag, typename RightTag>
struct max_assign
: max_assign_base<Left, Right, void>
{};
template<typename Left, typename Right, typename LeftTag, typename RightTag>
struct fdiv
: fdiv_base<Left, Right, void>
{};
/// INTERNAL ONLY
/// For back-compat only. Use fdiv.
template<typename Left, typename Right, typename LeftTag, typename RightTag>
struct average
: fdiv<Left, Right, LeftTag, RightTag>
{};
template<typename Arg, typename Tag>
struct as_min
: as_min_base<Arg, void>
{};
template<typename Arg, typename Tag>
struct as_max
: as_max_base<Arg, void>
{};
template<typename Arg, typename Tag>
struct as_zero
: as_zero_base<Arg, void>
{};
template<typename Arg, typename Tag>
struct as_one
: as_one_base<Arg, void>
{};
}
namespace op
{
template<typename To>
struct promote
: boost::detail::function1<functional::promote<To, _, typename functional::tag<To>::type, functional::tag<_> > >
{};
struct min_assign
: boost::detail::function2<functional::min_assign<_1, _2, functional::tag<_1>, functional::tag<_2> > >
{};
struct max_assign
: boost::detail::function2<functional::max_assign<_1, _2, functional::tag<_1>, functional::tag<_2> > >
{};
struct fdiv
: boost::detail::function2<functional::fdiv<_1, _2, functional::tag<_1>, functional::tag<_2> > >
{};
/// INTERNAL ONLY
struct average
: boost::detail::function2<functional::fdiv<_1, _2, functional::tag<_1>, functional::tag<_2> > >
{};
struct as_min
: boost::detail::function1<functional::as_min<_, functional::tag<_> > >
{};
struct as_max
: boost::detail::function1<functional::as_max<_, functional::tag<_> > >
{};
struct as_zero
: boost::detail::function1<functional::as_zero<_, functional::tag<_> > >
{};
struct as_one
: boost::detail::function1<functional::as_one<_, functional::tag<_> > >
{};
}
namespace
{
op::min_assign const &min_assign = boost::detail::pod_singleton<op::min_assign>::instance;
op::max_assign const &max_assign = boost::detail::pod_singleton<op::max_assign>::instance;
op::fdiv const &fdiv = boost::detail::pod_singleton<op::fdiv>::instance;
op::fdiv const &average = boost::detail::pod_singleton<op::fdiv>::instance; ///< INTERNAL ONLY
op::as_min const &as_min = boost::detail::pod_singleton<op::as_min>::instance;
op::as_max const &as_max = boost::detail::pod_singleton<op::as_max>::instance;
op::as_zero const &as_zero = boost::detail::pod_singleton<op::as_zero>::instance;
op::as_one const &as_one = boost::detail::pod_singleton<op::as_one>::instance;
BOOST_ACCUMULATORS_IGNORE_GLOBAL(min_assign)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(max_assign)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(fdiv)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(average)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(as_min)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(as_max)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(as_zero)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(as_one)
}
///////////////////////////////////////////////////////////////////////////////
// promote
template<typename To, typename From>
typename lazy_disable_if<is_const<From>, mpl::if_<is_same<To, From>, To &, To> >::type
promote(From &from)
{
return functional::promote<To, From>()(from);
}
template<typename To, typename From>
typename mpl::if_<is_same<To const, From const>, To const &, To const>::type
promote(From const &from)
{
return functional::promote<To const, From const>()(from);
}
template<typename T>
struct default_
{
typedef default_ type;
typedef T value_type;
static T const value;
operator T const & () const
{
return default_::value;
}
};
template<typename T>
T const default_<T>::value = T();
template<typename T>
struct one
{
typedef one type;
typedef T value_type;
static T const value;
operator T const & () const
{
return one::value;
}
};
template<typename T>
T const one<T>::value = T(1);
template<typename T>
struct zero
{
typedef zero type;
typedef T value_type;
static T const value;
operator T const & () const
{
return zero::value;
}
};
template<typename T>
T const zero<T>::value = T();
template<typename T>
struct one_or_default
: mpl::if_<is_empty<T>, default_<T>, one<T> >::type
{};
template<typename T>
struct zero_or_default
: mpl::if_<is_empty<T>, default_<T>, zero<T> >::type
{};
}} // namespace boost::numeric
#endif
@@ -0,0 +1,82 @@
///////////////////////////////////////////////////////////////////////////////
/// \file complex.hpp
///
// Copyright 2005 Eric Niebler. 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_NUMERIC_FUNCTIONAL_COMPLEX_HPP_EAN_01_17_2006
#define BOOST_NUMERIC_FUNCTIONAL_COMPLEX_HPP_EAN_01_17_2006
#ifdef BOOST_NUMERIC_FUNCTIONAL_HPP_INCLUDED
# error Include this file before boost/accumulators/numeric/functional.hpp
#endif
#include <complex>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/typeof/std/complex.hpp>
#include <boost/accumulators/numeric/functional_fwd.hpp>
namespace boost { namespace numeric { namespace operators
{
// So that the stats compile when Sample type is std::complex
template<typename T, typename U>
typename
disable_if<
mpl::or_<is_same<T, U>, is_same<std::complex<T>, U> >
, std::complex<T>
>::type
operator *(std::complex<T> ri, U const &u)
{
// BUGBUG promote result to typeof(T()*u) ?
return ri *= static_cast<T>(u);
}
template<typename T, typename U>
typename
disable_if<
mpl::or_<is_same<T, U>, is_same<std::complex<T>, U> >
, std::complex<T>
>::type
operator /(std::complex<T> ri, U const &u)
{
// BUGBUG promote result to typeof(T()*u) ?
return ri /= static_cast<T>(u);
}
}}} // namespace boost::numeric::operators
namespace boost { namespace numeric
{
namespace detail
{
template<typename T>
struct one_complex
{
static std::complex<T> const value;
};
template<typename T>
std::complex<T> const one_complex<T>::value
= std::complex<T>(numeric::one<T>::value, numeric::one<T>::value);
}
/// INTERNAL ONLY
///
template<typename T>
struct one<std::complex<T> >
: detail::one_complex<T>
{
typedef one type;
typedef std::complex<T> value_type;
operator value_type const & () const
{
return detail::one_complex<T>::value;
}
};
}} // namespace boost::numeric
#endif
@@ -0,0 +1,362 @@
///////////////////////////////////////////////////////////////////////////////
/// \file valarray.hpp
///
// Copyright 2005 Eric Niebler. 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_NUMERIC_FUNCTIONAL_VALARRAY_HPP_EAN_12_12_2005
#define BOOST_NUMERIC_FUNCTIONAL_VALARRAY_HPP_EAN_12_12_2005
#ifdef BOOST_NUMERIC_FUNCTIONAL_HPP_INCLUDED
# error Include this file before boost/accumulators/numeric/functional.hpp
#endif
#include <valarray>
#include <functional>
#include <boost/assert.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_scalar.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/typeof/std/valarray.hpp>
#include <boost/accumulators/numeric/functional_fwd.hpp>
namespace boost { namespace numeric
{
namespace operators
{
namespace acc_detail
{
template<typename Fun>
struct make_valarray
{
typedef std::valarray<typename Fun::result_type> type;
};
}
///////////////////////////////////////////////////////////////////////////////
// Handle valarray<Left> / Right where Right is a scalar and Right != Left.
template<typename Left, typename Right>
typename lazy_enable_if<
mpl::and_<is_scalar<Right>, mpl::not_<is_same<Left, Right> > >
, acc_detail::make_valarray<functional::divides<Left, Right> >
>::type
operator /(std::valarray<Left> const &left, Right const &right)
{
typedef typename functional::divides<Left, Right>::result_type value_type;
std::valarray<value_type> result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::divides(left[i], right);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle valarray<Left> * Right where Right is a scalar and Right != Left.
template<typename Left, typename Right>
typename lazy_enable_if<
mpl::and_<is_scalar<Right>, mpl::not_<is_same<Left, Right> > >
, acc_detail::make_valarray<functional::multiplies<Left, Right> >
>::type
operator *(std::valarray<Left> const &left, Right const &right)
{
typedef typename functional::multiplies<Left, Right>::result_type value_type;
std::valarray<value_type> result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::multiplies(left[i], right);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle valarray<Left> + valarray<Right> where Right != Left.
template<typename Left, typename Right>
typename lazy_disable_if<
is_same<Left, Right>
, acc_detail::make_valarray<functional::plus<Left, Right> >
>::type
operator +(std::valarray<Left> const &left, std::valarray<Right> const &right)
{
typedef typename functional::plus<Left, Right>::result_type value_type;
std::valarray<value_type> result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::plus(left[i], right[i]);
}
return result;
}
}
namespace functional
{
struct std_valarray_tag;
template<typename T>
struct tag<std::valarray<T> >
{
typedef std_valarray_tag type;
};
#ifdef __GLIBCXX__
template<typename T, typename U>
struct tag<std::_Expr<T, U> >
{
typedef std_valarray_tag type;
};
#endif
/// INTERNAL ONLY
///
// This is necessary because the GCC stdlib uses expression templates, and
// typeof(som-valarray-expression) is not an instance of std::valarray
#define BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(Name, Op) \
template<typename Left, typename Right> \
struct Name<Left, Right, std_valarray_tag, std_valarray_tag> \
{ \
typedef Left first_argument_type; \
typedef Right second_argument_type; \
typedef typename Left::value_type left_value_type; \
typedef typename Right::value_type right_value_type; \
typedef \
std::valarray< \
typename Name<left_value_type, right_value_type>::result_type \
> \
result_type; \
result_type \
operator ()(Left &left, Right &right) const \
{ \
return numeric::promote<std::valarray<left_value_type> >(left) \
Op numeric::promote<std::valarray<right_value_type> >(right); \
} \
}; \
template<typename Left, typename Right> \
struct Name<Left, Right, std_valarray_tag, void> \
{ \
typedef Left first_argument_type; \
typedef Right second_argument_type; \
typedef typename Left::value_type left_value_type; \
typedef \
std::valarray< \
typename Name<left_value_type, Right>::result_type \
> \
result_type; \
result_type \
operator ()(Left &left, Right &right) const \
{ \
return numeric::promote<std::valarray<left_value_type> >(left) Op right;\
} \
}; \
template<typename Left, typename Right> \
struct Name<Left, Right, void, std_valarray_tag> \
{ \
typedef Left first_argument_type; \
typedef Right second_argument_type; \
typedef typename Right::value_type right_value_type; \
typedef \
std::valarray< \
typename Name<Left, right_value_type>::result_type \
> \
result_type; \
result_type \
operator ()(Left &left, Right &right) const \
{ \
return left Op numeric::promote<std::valarray<right_value_type> >(right);\
} \
};
BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(plus, +)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(minus, -)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(multiplies, *)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(divides, /)
BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP(modulus, %)
#undef BOOST_NUMERIC_FUNCTIONAL_DEFINE_VALARRAY_BIN_OP
///////////////////////////////////////////////////////////////////////////////
// element-wise min of std::valarray
template<typename Left, typename Right>
struct min_assign<Left, Right, std_valarray_tag, std_valarray_tag>
{
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const
{
BOOST_ASSERT(left.size() == right.size());
for(std::size_t i = 0, size = left.size(); i != size; ++i)
{
if(numeric::less(right[i], left[i]))
{
left[i] = right[i];
}
}
}
};
///////////////////////////////////////////////////////////////////////////////
// element-wise max of std::valarray
template<typename Left, typename Right>
struct max_assign<Left, Right, std_valarray_tag, std_valarray_tag>
{
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const
{
BOOST_ASSERT(left.size() == right.size());
for(std::size_t i = 0, size = left.size(); i != size; ++i)
{
if(numeric::greater(right[i], left[i]))
{
left[i] = right[i];
}
}
}
};
// partial specialization of numeric::fdiv<> for std::valarray.
template<typename Left, typename Right, typename RightTag>
struct fdiv<Left, Right, std_valarray_tag, RightTag>
: mpl::if_<
are_integral<typename Left::value_type, Right>
, divides<Left, double const>
, divides<Left, Right>
>::type
{};
// promote
template<typename To, typename From>
struct promote<To, From, std_valarray_tag, std_valarray_tag>
{
typedef From argument_type;
typedef To result_type;
To operator ()(From &arr) const
{
typename remove_const<To>::type res(arr.size());
for(std::size_t i = 0, size = arr.size(); i != size; ++i)
{
res[i] = numeric::promote<typename To::value_type>(arr[i]);
}
return res;
}
};
template<typename ToFrom>
struct promote<ToFrom, ToFrom, std_valarray_tag, std_valarray_tag>
{
typedef ToFrom argument_type;
typedef ToFrom result_type;
ToFrom &operator ()(ToFrom &tofrom) const
{
return tofrom;
}
};
// for "promoting" a std::valarray<bool> to a bool, useful for
// comparing 2 valarrays for equality:
// if(numeric::promote<bool>(a == b))
template<typename From>
struct promote<bool, From, void, std_valarray_tag>
{
typedef From argument_type;
typedef bool result_type;
bool operator ()(From &arr) const
{
BOOST_MPL_ASSERT((is_same<bool, typename From::value_type>));
for(std::size_t i = 0, size = arr.size(); i != size; ++i)
{
if(!arr[i])
{
return false;
}
}
return true;
}
};
template<typename From>
struct promote<bool const, From, void, std_valarray_tag>
: promote<bool, From, void, std_valarray_tag>
{};
///////////////////////////////////////////////////////////////////////////////
// functional::as_min
template<typename T>
struct as_min<T, std_valarray_tag>
{
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(numeric::as_min(arr[0]), arr.size());
}
};
///////////////////////////////////////////////////////////////////////////////
// functional::as_max
template<typename T>
struct as_max<T, std_valarray_tag>
{
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(numeric::as_max(arr[0]), arr.size());
}
};
///////////////////////////////////////////////////////////////////////////////
// functional::as_zero
template<typename T>
struct as_zero<T, std_valarray_tag>
{
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(numeric::as_zero(arr[0]), arr.size());
}
};
///////////////////////////////////////////////////////////////////////////////
// functional::as_one
template<typename T>
struct as_one<T, std_valarray_tag>
{
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(numeric::as_one(arr[0]), arr.size());
}
};
} // namespace functional
}} // namespace boost::numeric
#endif
@@ -0,0 +1,347 @@
///////////////////////////////////////////////////////////////////////////////
/// \file vector.hpp
///
// Copyright 2005 Eric Niebler. 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_NUMERIC_FUNCTIONAL_VECTOR_HPP_EAN_12_12_2005
#define BOOST_NUMERIC_FUNCTIONAL_VECTOR_HPP_EAN_12_12_2005
#ifdef BOOST_NUMERIC_FUNCTIONAL_HPP_INCLUDED
# error Include this file before boost/accumulators/numeric/functional.hpp
#endif
#include <vector>
#include <functional>
#include <boost/assert.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/not.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_scalar.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/typeof/std/vector.hpp>
#include <boost/accumulators/numeric/functional_fwd.hpp>
namespace boost { namespace numeric
{
namespace operators
{
namespace acc_detail
{
template<typename Fun>
struct make_vector
{
typedef std::vector<typename Fun::result_type> type;
};
}
///////////////////////////////////////////////////////////////////////////////
// Handle vector<Left> / Right where Right is a scalar.
template<typename Left, typename Right>
typename lazy_enable_if<
is_scalar<Right>
, acc_detail::make_vector<functional::divides<Left, Right> >
>::type
operator /(std::vector<Left> const &left, Right const &right)
{
typedef typename functional::divides<Left, Right>::result_type value_type;
std::vector<value_type> result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::divides(left[i], right);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle vector<Left> / vector<Right>.
template<typename Left, typename Right>
std::vector<typename functional::divides<Left, Right>::result_type>
operator /(std::vector<Left> const &left, std::vector<Right> const &right)
{
typedef typename functional::divides<Left, Right>::result_type value_type;
std::vector<value_type> result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::divides(left[i], right[i]);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle vector<Left> * Right where Right is a scalar.
template<typename Left, typename Right>
typename lazy_enable_if<
is_scalar<Right>
, acc_detail::make_vector<functional::multiplies<Left, Right> >
>::type
operator *(std::vector<Left> const &left, Right const &right)
{
typedef typename functional::multiplies<Left, Right>::result_type value_type;
std::vector<value_type> result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::multiplies(left[i], right);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle Left * vector<Right> where Left is a scalar.
template<typename Left, typename Right>
typename lazy_enable_if<
is_scalar<Left>
, acc_detail::make_vector<functional::multiplies<Left, Right> >
>::type
operator *(Left const &left, std::vector<Right> const &right)
{
typedef typename functional::multiplies<Left, Right>::result_type value_type;
std::vector<value_type> result(right.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::multiplies(left, right[i]);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle vector<Left> * vector<Right>
template<typename Left, typename Right>
std::vector<typename functional::multiplies<Left, Right>::result_type>
operator *(std::vector<Left> const &left, std::vector<Right> const &right)
{
typedef typename functional::multiplies<Left, Right>::result_type value_type;
std::vector<value_type> result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::multiplies(left[i], right[i]);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle vector<Left> + vector<Right>
template<typename Left, typename Right>
std::vector<typename functional::plus<Left, Right>::result_type>
operator +(std::vector<Left> const &left, std::vector<Right> const &right)
{
typedef typename functional::plus<Left, Right>::result_type value_type;
std::vector<value_type> result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::plus(left[i], right[i]);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle vector<Left> - vector<Right>
template<typename Left, typename Right>
std::vector<typename functional::minus<Left, Right>::result_type>
operator -(std::vector<Left> const &left, std::vector<Right> const &right)
{
typedef typename functional::minus<Left, Right>::result_type value_type;
std::vector<value_type> result(left.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::minus(left[i], right[i]);
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// Handle vector<Left> += vector<Left>
template<typename Left>
std::vector<Left> &
operator +=(std::vector<Left> &left, std::vector<Left> const &right)
{
BOOST_ASSERT(left.size() == right.size());
for(std::size_t i = 0, size = left.size(); i != size; ++i)
{
numeric::plus_assign(left[i], right[i]);
}
return left;
}
///////////////////////////////////////////////////////////////////////////////
// Handle -vector<Arg>
template<typename Arg>
std::vector<typename functional::unary_minus<Arg>::result_type>
operator -(std::vector<Arg> const &arg)
{
typedef typename functional::unary_minus<Arg>::result_type value_type;
std::vector<value_type> result(arg.size());
for(std::size_t i = 0, size = result.size(); i != size; ++i)
{
result[i] = numeric::unary_minus(arg[i]);
}
return result;
}
}
namespace functional
{
struct std_vector_tag;
template<typename T, typename Al>
struct tag<std::vector<T, Al> >
{
typedef std_vector_tag type;
};
///////////////////////////////////////////////////////////////////////////////
// element-wise min of std::vector
template<typename Left, typename Right>
struct min_assign<Left, Right, std_vector_tag, std_vector_tag>
{
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const
{
BOOST_ASSERT(left.size() == right.size());
for(std::size_t i = 0, size = left.size(); i != size; ++i)
{
if(numeric::less(right[i], left[i]))
{
left[i] = right[i];
}
}
}
};
///////////////////////////////////////////////////////////////////////////////
// element-wise max of std::vector
template<typename Left, typename Right>
struct max_assign<Left, Right, std_vector_tag, std_vector_tag>
{
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef void result_type;
void operator ()(Left &left, Right &right) const
{
BOOST_ASSERT(left.size() == right.size());
for(std::size_t i = 0, size = left.size(); i != size; ++i)
{
if(numeric::greater(right[i], left[i]))
{
left[i] = right[i];
}
}
}
};
// partial specialization for std::vector.
template<typename Left, typename Right>
struct fdiv<Left, Right, std_vector_tag, void>
: mpl::if_<
are_integral<typename Left::value_type, Right>
, divides<Left, double const>
, divides<Left, Right>
>::type
{};
// promote
template<typename To, typename From>
struct promote<To, From, std_vector_tag, std_vector_tag>
{
typedef From argument_type;
typedef To result_type;
To operator ()(From &arr) const
{
typename remove_const<To>::type res(arr.size());
for(std::size_t i = 0, size = arr.size(); i != size; ++i)
{
res[i] = numeric::promote<typename To::value_type>(arr[i]);
}
return res;
}
};
template<typename ToFrom>
struct promote<ToFrom, ToFrom, std_vector_tag, std_vector_tag>
{
typedef ToFrom argument_type;
typedef ToFrom result_type;
ToFrom &operator ()(ToFrom &tofrom) const
{
return tofrom;
}
};
///////////////////////////////////////////////////////////////////////////////
// functional::as_min
template<typename T>
struct as_min<T, std_vector_tag>
{
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(arr.size(), numeric::as_min(arr[0]));
}
};
///////////////////////////////////////////////////////////////////////////////
// functional::as_max
template<typename T>
struct as_max<T, std_vector_tag>
{
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(arr.size(), numeric::as_max(arr[0]));
}
};
///////////////////////////////////////////////////////////////////////////////
// functional::as_zero
template<typename T>
struct as_zero<T, std_vector_tag>
{
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(arr.size(), numeric::as_zero(arr[0]));
}
};
///////////////////////////////////////////////////////////////////////////////
// functional::as_one
template<typename T>
struct as_one<T, std_vector_tag>
{
typedef T argument_type;
typedef typename remove_const<T>::type result_type;
typename remove_const<T>::type operator ()(T &arr) const
{
return 0 == arr.size()
? T()
: T(arr.size(), numeric::as_one(arr[0]));
}
};
} // namespace functional
}} // namespace boost::numeric
#endif
@@ -0,0 +1,221 @@
///////////////////////////////////////////////////////////////////////////////
/// \file functional_fwd.hpp
///
// Copyright 2005 Eric Niebler. 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_NUMERIC_FUNCTIONAL_FWD_HPP_EAN_08_12_2005
#define BOOST_NUMERIC_FUNCTIONAL_FWD_HPP_EAN_08_12_2005
#include <boost/mpl/if.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_const.hpp>
namespace boost { namespace numeric
{
// For using directives -- this namespace may be re-opened elsewhere
namespace operators
{}
namespace op
{
using mpl::_;
using mpl::_1;
using mpl::_2;
}
namespace functional
{
using namespace operators;
template<typename T>
struct tag
{
typedef void type;
};
template<typename T>
struct tag<T const>
: tag<T>
{};
template<typename T>
struct tag<T volatile>
: tag<T>
{};
template<typename T>
struct tag<T const volatile>
: tag<T>
{};
template<typename T>
struct static_;
template<typename A0, typename A1>
struct are_integral;
}
/// INTERNAL ONLY
///
#define BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(Name, Op) \
namespace functional \
{ \
template<typename Arg, typename EnableIf = void> \
struct Name ## _base; \
template<typename Arg, typename ArgTag = typename tag<Arg>::type> \
struct Name; \
} \
namespace op \
{ \
struct Name; \
} \
namespace \
{ \
extern op::Name const &Name; \
}
/// INTERNAL ONLY
///
#define BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(Name) \
namespace functional \
{ \
template<typename Left, typename Right, typename EnableIf = void> \
struct result_of_ ## Name; \
template<typename Left, typename Right, typename EnableIf = void> \
struct Name ## _base; \
template< \
typename Left \
, typename Right \
, typename LeftTag = typename tag<Left>::type \
, typename RightTag = typename tag<Right>::type \
> \
struct Name; \
} \
namespace op \
{ \
struct Name; \
} \
namespace \
{ \
extern op::Name const &Name; \
}
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(plus)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(minus)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(multiplies)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(divides)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(modulus)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(greater)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(greater_equal)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(less)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(less_equal)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(equal_to)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(not_equal_to)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(assign)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(plus_assign)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(minus_assign)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(multiplies_assign)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(divides_assign)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(modulus_assign)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(unary_plus, +)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(unary_minus, -)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(complement, ~)
BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(logical_not, !)
#undef BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP
#undef BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP
namespace functional
{
template<typename To, typename From, typename EnableIf = void>
struct promote_base;
template<typename Left, typename Right, typename EnableIf = void>
struct min_assign_base;
template<typename Left, typename Right, typename EnableIf = void>
struct max_assign_base;
template<typename Left, typename Right, typename EnableIf = void>
struct fdiv_base;
template<typename Arg, typename EnableIf = void>
struct as_min_base;
template<typename Arg, typename EnableIf = void>
struct as_max_base;
template<typename Arg, typename EnableIf = void>
struct as_zero_base;
template<typename Arg, typename EnableIf = void>
struct as_one_base;
template<typename To, typename From, typename ToTag = typename tag<To>::type, typename FromTag = typename tag<From>::type>
struct promote;
template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
struct min_assign;
template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
struct max_assign;
template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
struct fdiv;
template<typename Arg, typename Tag = typename tag<Arg>::type>
struct as_min;
template<typename Arg, typename Tag = typename tag<Arg>::type>
struct as_max;
template<typename Arg, typename Tag = typename tag<Arg>::type>
struct as_zero;
template<typename Arg, typename Tag = typename tag<Arg>::type>
struct as_one;
}
namespace op
{
template<typename To>
struct promote;
struct min_assign;
struct max_assign;
struct fdiv;
struct as_min;
struct as_max;
struct as_zero;
struct as_one;
}
namespace
{
extern op::min_assign const &min_assign;
extern op::max_assign const &max_assign;
extern op::fdiv const &fdiv;
extern op::as_min const &as_min;
extern op::as_max const &as_max;
extern op::as_zero const &as_zero;
extern op::as_one const &as_one;
}
template<typename To, typename From>
typename lazy_disable_if<is_const<From>, mpl::if_<is_same<To, From>, To &, To> >::type
promote(From &from);
template<typename To, typename From>
typename mpl::if_<is_same<To const, From const>, To const &, To const>::type
promote(From const &from);
template<typename T>
struct default_;
template<typename T>
struct one;
template<typename T>
struct zero;
template<typename T>
struct one_or_default;
template<typename T>
struct zero_or_default;
}} // namespace boost::numeric
#endif
@@ -0,0 +1,61 @@
///////////////////////////////////////////////////////////////////////////////
/// \file statistics.hpp
/// Includes all of the Statistical Accumulators Library
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_HPP_EAN_01_17_2006
#define BOOST_ACCUMULATORS_STATISTICS_HPP_EAN_01_17_2006
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/covariance.hpp>
#include <boost/accumulators/statistics/density.hpp>
#include <boost/accumulators/statistics/error_of.hpp>
#include <boost/accumulators/statistics/error_of_mean.hpp>
#include <boost/accumulators/statistics/extended_p_square.hpp>
#include <boost/accumulators/statistics/extended_p_square_quantile.hpp>
#include <boost/accumulators/statistics/kurtosis.hpp>
#include <boost/accumulators/statistics/max.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/median.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/peaks_over_threshold.hpp>
#include <boost/accumulators/statistics/pot_tail_mean.hpp>
#include <boost/accumulators/statistics/pot_quantile.hpp>
#include <boost/accumulators/statistics/p_square_cumul_dist.hpp>
#include <boost/accumulators/statistics/p_square_quantile.hpp>
#include <boost/accumulators/statistics/skewness.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/sum_kahan.hpp>
#include <boost/accumulators/statistics/tail.hpp>
#include <boost/accumulators/statistics/tail_quantile.hpp>
#include <boost/accumulators/statistics/tail_mean.hpp>
#include <boost/accumulators/statistics/tail_variate.hpp>
#include <boost/accumulators/statistics/tail_variate_means.hpp>
#include <boost/accumulators/statistics/variance.hpp>
#include <boost/accumulators/statistics/weighted_covariance.hpp>
#include <boost/accumulators/statistics/weighted_density.hpp>
#include <boost/accumulators/statistics/weighted_kurtosis.hpp>
#include <boost/accumulators/statistics/weighted_extended_p_square.hpp>
#include <boost/accumulators/statistics/weighted_mean.hpp>
#include <boost/accumulators/statistics/weighted_median.hpp>
#include <boost/accumulators/statistics/weighted_moment.hpp>
#include <boost/accumulators/statistics/weighted_peaks_over_threshold.hpp>
#include <boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp>
#include <boost/accumulators/statistics/weighted_p_square_quantile.hpp>
#include <boost/accumulators/statistics/weighted_skewness.hpp>
#include <boost/accumulators/statistics/weighted_sum.hpp>
#include <boost/accumulators/statistics/weighted_sum_kahan.hpp>
#include <boost/accumulators/statistics/weighted_tail_quantile.hpp>
#include <boost/accumulators/statistics/weighted_tail_mean.hpp>
#include <boost/accumulators/statistics/weighted_tail_variate_means.hpp>
#include <boost/accumulators/statistics/weighted_variance.hpp>
#include <boost/accumulators/statistics/with_error.hpp>
#include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
#include <boost/accumulators/statistics/variates/covariate.hpp>
#endif
@@ -0,0 +1,87 @@
///////////////////////////////////////////////////////////////////////////////
// count.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_COUNT_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_COUNT_HPP_EAN_28_10_2005
#include <boost/mpl/always.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// count_impl
struct count_impl
: accumulator_base
{
// for boost::result_of
typedef std::size_t result_type;
count_impl(dont_care)
: cnt(0)
{
}
void operator ()(dont_care)
{
++this->cnt;
}
result_type result(dont_care) const
{
return this->cnt;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */)
{
ar & cnt;
}
private:
std::size_t cnt;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::count
//
namespace tag
{
struct count
: depends_on<>
{
/// INTERNAL ONLY
///
typedef mpl::always<accumulators::impl::count_impl> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::count
//
namespace extract
{
extractor<tag::count> const count = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(count)
}
using extract::count;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,219 @@
///////////////////////////////////////////////////////////////////////////////
// covariance.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_COVARIANCE_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_COVARIANCE_HPP_DE_01_01_2006
#include <vector>
#include <limits>
#include <numeric>
#include <functional>
#include <complex>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/range.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/type_traits/is_scalar.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/mean.hpp>
namespace boost { namespace numeric
{
namespace functional
{
struct std_vector_tag;
///////////////////////////////////////////////////////////////////////////////
// functional::outer_product
template<typename Left, typename Right, typename EnableIf = void>
struct outer_product_base
: functional::multiplies<Left, Right>
{};
template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
struct outer_product
: outer_product_base<Left, Right, void>
{};
template<typename Left, typename Right>
struct outer_product<Left, Right, std_vector_tag, std_vector_tag>
{
typedef Left first_argument_type;
typedef Right second_argument_type;
typedef
ublas::matrix<
typename functional::multiplies<
typename Left::value_type
, typename Right::value_type
>::result_type
>
result_type;
result_type
operator ()(Left & left, Right & right) const
{
std::size_t left_size = left.size();
std::size_t right_size = right.size();
result_type result(left_size, right_size);
for (std::size_t i = 0; i < left_size; ++i)
for (std::size_t j = 0; j < right_size; ++j)
result(i,j) = numeric::multiplies(left[i], right[j]);
return result;
}
};
}
namespace op
{
struct outer_product
: boost::detail::function2<functional::outer_product<_1, _2, functional::tag<_1>, functional::tag<_2> > >
{};
}
namespace
{
op::outer_product const &outer_product = boost::detail::pod_singleton<op::outer_product>::instance;
}
}}
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// covariance_impl
//
/**
@brief Covariance Estimator
An iterative Monte Carlo estimator for the covariance \f$\mathrm{Cov}(X,X')\f$, where \f$X\f$ is a sample
and \f$X'\f$ is a variate, is given by:
\f[
\hat{c}_n = \frac{n-1}{n} \hat{c}_{n-1} + \frac{1}{n-1}(X_n - \hat{\mu}_n)(X_n' - \hat{\mu}_n'),\quad n\ge2,\quad\hat{c}_1 = 0,
\f]
\f$\hat{\mu}_n\f$ and \f$\hat{\mu}_n'\f$ being the means of the samples and variates.
*/
template<typename Sample, typename VariateType, typename VariateTag>
struct covariance_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type sample_type;
typedef typename numeric::functional::fdiv<VariateType, std::size_t>::result_type variate_type;
// for boost::result_of
typedef typename numeric::functional::outer_product<sample_type, variate_type>::result_type result_type;
template<typename Args>
covariance_impl(Args const &args)
: cov_(
numeric::outer_product(
numeric::fdiv(args[sample | Sample()], (std::size_t)1)
, numeric::fdiv(args[parameter::keyword<VariateTag>::get() | VariateType()], (std::size_t)1)
)
)
{
}
template<typename Args>
void operator ()(Args const &args)
{
std::size_t cnt = count(args);
if (cnt > 1)
{
extractor<tag::mean_of_variates<VariateType, VariateTag> > const some_mean_of_variates = {};
this->cov_ = this->cov_*(cnt-1.)/cnt
+ numeric::outer_product(
some_mean_of_variates(args) - args[parameter::keyword<VariateTag>::get()]
, mean(args) - args[sample]
) / (cnt-1.);
}
}
result_type result(dont_care) const
{
return this->cov_;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & cov_;
}
private:
result_type cov_;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::covariance
//
namespace tag
{
template<typename VariateType, typename VariateTag>
struct covariance
: depends_on<count, mean, mean_of_variates<VariateType, VariateTag> >
{
typedef accumulators::impl::covariance_impl<mpl::_1, VariateType, VariateTag> impl;
};
struct abstract_covariance
: depends_on<>
{
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::covariance
//
namespace extract
{
extractor<tag::abstract_covariance> const covariance = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(covariance)
}
using extract::covariance;
template<typename VariateType, typename VariateTag>
struct feature_of<tag::covariance<VariateType, VariateTag> >
: feature_of<tag::abstract_covariance>
{
};
// So that covariance can be automatically substituted with
// weighted_covariance when the weight parameter is non-void.
template<typename VariateType, typename VariateTag>
struct as_weighted_feature<tag::covariance<VariateType, VariateTag> >
{
typedef tag::weighted_covariance<VariateType, VariateTag> type;
};
template<typename VariateType, typename VariateTag>
struct feature_of<tag::weighted_covariance<VariateType, VariateTag> >
: feature_of<tag::covariance<VariateType, VariateTag> >
{};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,266 @@
///////////////////////////////////////////////////////////////////////////////
// density.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_DENSITY_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_DENSITY_HPP_DE_01_01_2006
#include <vector>
#include <limits>
#include <functional>
#include <boost/range.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/max.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/utility.hpp>
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////////
// cache_size and num_bins named parameters
//
BOOST_PARAMETER_NESTED_KEYWORD(tag, density_cache_size, cache_size)
BOOST_PARAMETER_NESTED_KEYWORD(tag, density_num_bins, num_bins)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(density_cache_size)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(density_num_bins)
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// density_impl
// density histogram
/**
@brief Histogram density estimator
The histogram density estimator returns a histogram of the sample distribution. The positions and sizes of the bins
are determined using a specifiable number of cached samples (cache_size). The range between the minimum and the
maximum of the cached samples is subdivided into a specifiable number of bins (num_bins) of same size. Additionally,
an under- and an overflow bin is added to capture future under- and overflow samples. Once the bins are determined,
the cached samples and all subsequent samples are added to the correct bins. At the end, a range of std::pair is
return, where each pair contains the position of the bin (lower bound) and the samples count (normalized with the
total number of samples).
@param density_cache_size Number of first samples used to determine min and max.
@param density_num_bins Number of bins (two additional bins collect under- and overflow samples).
*/
template<typename Sample>
struct density_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
typedef std::vector<float_type> array_type;
// for boost::result_of
typedef iterator_range<typename histogram_type::iterator> result_type;
template<typename Args>
density_impl(Args const &args)
: cache_size(args[density_cache_size])
, cache(cache_size)
, num_bins(args[density_num_bins])
, samples_in_bin(num_bins + 2, 0.)
, bin_positions(num_bins + 2)
, histogram(
num_bins + 2
, std::make_pair(
numeric::fdiv(args[sample | Sample()],(std::size_t)1)
, numeric::fdiv(args[sample | Sample()],(std::size_t)1)
)
)
, is_dirty(true)
{
}
template<typename Args>
void operator ()(Args const &args)
{
this->is_dirty = true;
std::size_t cnt = count(args);
// Fill up cache with cache_size first samples
if (cnt <= this->cache_size)
{
this->cache[cnt - 1] = args[sample];
}
// Once cache_size samples have been accumulated, create num_bins bins of same size between
// the minimum and maximum of the cached samples as well as under and overflow bins.
// Store their lower bounds (bin_positions) and fill the bins with the cached samples (samples_in_bin).
if (cnt == this->cache_size)
{
float_type minimum = numeric::fdiv((min)(args), (std::size_t)1);
float_type maximum = numeric::fdiv((max)(args), (std::size_t)1);
float_type bin_size = numeric::fdiv(maximum - minimum, this->num_bins );
// determine bin positions (their lower bounds)
for (std::size_t i = 0; i < this->num_bins + 2; ++i)
{
this->bin_positions[i] = minimum + (i - 1.) * bin_size;
}
for (typename array_type::const_iterator iter = this->cache.begin(); iter != this->cache.end(); ++iter)
{
if (*iter < this->bin_positions[1])
{
++(this->samples_in_bin[0]);
}
else if (*iter >= this->bin_positions[this->num_bins + 1])
{
++(this->samples_in_bin[this->num_bins + 1]);
}
else
{
typename array_type::iterator it = std::upper_bound(
this->bin_positions.begin()
, this->bin_positions.end()
, *iter
);
std::size_t d = std::distance(this->bin_positions.begin(), it);
++(this->samples_in_bin[d - 1]);
}
}
}
// Add each subsequent sample to the correct bin
else if (cnt > this->cache_size)
{
if (args[sample] < this->bin_positions[1])
{
++(this->samples_in_bin[0]);
}
else if (args[sample] >= this->bin_positions[this->num_bins + 1])
{
++(this->samples_in_bin[this->num_bins + 1]);
}
else
{
typename array_type::iterator it = std::upper_bound(
this->bin_positions.begin()
, this->bin_positions.end()
, args[sample]
);
std::size_t d = std::distance(this->bin_positions.begin(), it);
++(this->samples_in_bin[d - 1]);
}
}
}
/**
@pre The number of samples must meet or exceed the cache size
*/
template<typename Args>
result_type result(Args const &args) const
{
if (this->is_dirty)
{
this->is_dirty = false;
// creates a vector of std::pair where each pair i holds
// the values bin_positions[i] (x-axis of histogram) and
// samples_in_bin[i] / cnt (y-axis of histogram).
for (std::size_t i = 0; i < this->num_bins + 2; ++i)
{
this->histogram[i] = std::make_pair(this->bin_positions[i], numeric::fdiv(this->samples_in_bin[i], count(args)));
}
}
// returns a range of pairs
return make_iterator_range(this->histogram);
}
// make this accumulator serializeable
// TODO split to save/load and check on parameters provided in ctor
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & cache_size;
ar & cache;
ar & num_bins;
ar & samples_in_bin;
ar & bin_positions;
ar & histogram;
ar & is_dirty;
}
private:
std::size_t cache_size; // number of cached samples
array_type cache; // cache to store the first cache_size samples
std::size_t num_bins; // number of bins
array_type samples_in_bin; // number of samples in each bin
array_type bin_positions; // lower bounds of bins
mutable histogram_type histogram; // histogram
mutable bool is_dirty;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::density
//
namespace tag
{
struct density
: depends_on<count, min, max>
, density_cache_size
, density_num_bins
{
/// INTERNAL ONLY
///
typedef accumulators::impl::density_impl<mpl::_1> impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::density::cache_size named parameter
/// tag::density::num_bins named parameter
static boost::parameter::keyword<density_cache_size> const cache_size;
static boost::parameter::keyword<density_num_bins> const num_bins;
#endif
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::density
//
namespace extract
{
extractor<tag::density> const density = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(density)
}
using extract::density;
// So that density can be automatically substituted
// with weighted_density when the weight parameter is non-void.
template<>
struct as_weighted_feature<tag::density>
{
typedef tag::weighted_density type;
};
template<>
struct feature_of<tag::weighted_density>
: feature_of<tag::density>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,99 @@
///////////////////////////////////////////////////////////////////////////////
// error_of.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_ERROR_OF_HPP_EAN_29_11_2005
#define BOOST_ACCUMULATORS_STATISTICS_ERROR_OF_HPP_EAN_29_11_2005
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
/// INTERNAL ONLY
///
template<typename Feature>
struct this_feature_has_no_error_calculation
: mpl::false_
{
};
///////////////////////////////////////////////////////////////////////////////
// error_of_impl
/// INTERNAL ONLY
///
template<typename Sample, typename Feature>
struct error_of_impl
: accumulator_base
{
// TODO: specialize this on the specific features that have errors we're
// interested in.
BOOST_MPL_ASSERT((this_feature_has_no_error_calculation<Feature>));
// for boost::result_of
typedef int result_type;
error_of_impl(dont_care)
{
}
result_type result(dont_care) const
{
return 0;
}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::error_of
//
namespace tag
{
template<typename Feature>
struct error_of
: depends_on<Feature>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::error_of_impl<mpl::_1, Feature> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::error_of
//
namespace extract
{
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, error_of, (typename))
}
using extract::error_of;
// make tag::error_of<tag::feature(modifier)> work
template<typename Feature>
struct as_feature<tag::error_of<Feature> >
{
typedef tag::error_of<typename as_feature<Feature>::type> type;
};
// make error_of<tag::mean> work with non-void weights (should become
// error_of<tag::weighted_mean>
template<typename Feature>
struct as_weighted_feature<tag::error_of<Feature> >
{
typedef tag::error_of<typename as_weighted_feature<Feature>::type> type;
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,73 @@
///////////////////////////////////////////////////////////////////////////////
// error_of.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_ERROR_OF_MEAN_HPP_EAN_27_03_2006
#define BOOST_ACCUMULATORS_STATISTICS_ERROR_OF_MEAN_HPP_EAN_27_03_2006
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/error_of.hpp>
#include <boost/accumulators/statistics/variance.hpp>
#include <boost/accumulators/statistics/count.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// error_of_mean_impl
template<typename Sample, typename Variance>
struct error_of_mean_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
error_of_mean_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
using namespace std;
extractor<Variance> const variance = {};
return sqrt(numeric::fdiv(variance(args), count(args) - 1));
}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::error_of
//
namespace tag
{
template<>
struct error_of<mean>
: depends_on<lazy_variance, count>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::error_of_mean_impl<mpl::_1, lazy_variance> impl;
};
template<>
struct error_of<immediate_mean>
: depends_on<variance, count>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::error_of_mean_impl<mpl::_1, variance> impl;
};
}
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,309 @@
///////////////////////////////////////////////////////////////////////////////
// extended_p_square.hpp
//
// Copyright 2005 Daniel Egloff. 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_ACCUMULATORS_STATISTICS_EXTENDED_SINGLE_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_EXTENDED_SINGLE_HPP_DE_01_01_2006
#include <vector>
#include <functional>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/times2_iterator.hpp>
#include <boost/serialization/vector.hpp>
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////////
// probabilities named parameter
//
BOOST_PARAMETER_NESTED_KEYWORD(tag, extended_p_square_probabilities, probabilities)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(extended_p_square_probabilities)
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// extended_p_square_impl
// multiple quantile estimation
/**
@brief Multiple quantile estimation with the extended \f$P^2\f$ algorithm
Extended \f$P^2\f$ algorithm for estimation of several quantiles without storing samples.
Assume that \f$m\f$ quantiles \f$\xi_{p_1}, \ldots, \xi_{p_m}\f$ are to be estimated.
Instead of storing the whole sample cumulative distribution, the algorithm maintains only
\f$m+2\f$ principal markers and \f$m+1\f$ middle markers, whose positions are updated
with each sample and whose heights are adjusted (if necessary) using a piecewise-parablic
formula. The heights of these central markers are the current estimates of the quantiles
and returned as an iterator range.
For further details, see
K. E. E. Raatikainen, Simultaneous estimation of several quantiles, Simulation, Volume 49,
Number 4 (October), 1986, p. 159-164.
The extended \f$ P^2 \f$ algorithm generalizes the \f$ P^2 \f$ algorithm of
R. Jain and I. Chlamtac, The P^2 algorithm for dynamic calculation of quantiles and
histograms without storing observations, Communications of the ACM,
Volume 28 (October), Number 10, 1985, p. 1076-1085.
@param extended_p_square_probabilities A vector of quantile probabilities.
*/
template<typename Sample>
struct extended_p_square_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
typedef std::vector<float_type> array_type;
// for boost::result_of
typedef iterator_range<
detail::lvalue_index_iterator<
permutation_iterator<
typename array_type::const_iterator
, detail::times2_iterator
>
>
> result_type;
template<typename Args>
extended_p_square_impl(Args const &args)
: probabilities(
boost::begin(args[extended_p_square_probabilities])
, boost::end(args[extended_p_square_probabilities])
)
, heights(2 * probabilities.size() + 3)
, actual_positions(heights.size())
, desired_positions(heights.size())
, positions_increments(heights.size())
{
std::size_t num_quantiles = this->probabilities.size();
std::size_t num_markers = this->heights.size();
for(std::size_t i = 0; i < num_markers; ++i)
{
this->actual_positions[i] = i + 1;
}
this->positions_increments[0] = 0.;
this->positions_increments[num_markers - 1] = 1.;
for(std::size_t i = 0; i < num_quantiles; ++i)
{
this->positions_increments[2 * i + 2] = probabilities[i];
}
for(std::size_t i = 0; i <= num_quantiles; ++i)
{
this->positions_increments[2 * i + 1] =
0.5 * (this->positions_increments[2 * i] + this->positions_increments[2 * i + 2]);
}
for(std::size_t i = 0; i < num_markers; ++i)
{
this->desired_positions[i] = 1. + 2. * (num_quantiles + 1.) * this->positions_increments[i];
}
}
template<typename Args>
void operator ()(Args const &args)
{
std::size_t cnt = count(args);
// m+2 principal markers and m+1 middle markers
std::size_t num_markers = 2 * this->probabilities.size() + 3;
// first accumulate num_markers samples
if(cnt <= num_markers)
{
this->heights[cnt - 1] = args[sample];
// complete the initialization of heights by sorting
if(cnt == num_markers)
{
std::sort(this->heights.begin(), this->heights.end());
}
}
else
{
std::size_t sample_cell = 1;
// find cell k = sample_cell such that heights[k-1] <= sample < heights[k]
if(args[sample] < this->heights[0])
{
this->heights[0] = args[sample];
sample_cell = 1;
}
else if(args[sample] >= this->heights[num_markers - 1])
{
this->heights[num_markers - 1] = args[sample];
sample_cell = num_markers - 1;
}
else
{
typedef typename array_type::iterator iterator;
iterator it = std::upper_bound(
this->heights.begin()
, this->heights.end()
, args[sample]
);
sample_cell = std::distance(this->heights.begin(), it);
}
// update actual positions of all markers above sample_cell index
for(std::size_t i = sample_cell; i < num_markers; ++i)
{
++this->actual_positions[i];
}
// update desired positions of all markers
for(std::size_t i = 0; i < num_markers; ++i)
{
this->desired_positions[i] += this->positions_increments[i];
}
// adjust heights and actual positions of markers 1 to num_markers-2 if necessary
for(std::size_t i = 1; i <= num_markers - 2; ++i)
{
// offset to desired position
float_type d = this->desired_positions[i] - this->actual_positions[i];
// offset to next position
float_type dp = this->actual_positions[i+1] - this->actual_positions[i];
// offset to previous position
float_type dm = this->actual_positions[i-1] - this->actual_positions[i];
// height ds
float_type hp = (this->heights[i+1] - this->heights[i]) / dp;
float_type hm = (this->heights[i-1] - this->heights[i]) / dm;
if((d >= 1 && dp > 1) || (d <= -1 && dm < -1))
{
short sign_d = static_cast<short>(d / std::abs(d));
float_type h = this->heights[i] + sign_d / (dp - dm) * ((sign_d - dm)*hp
+ (dp - sign_d) * hm);
// try adjusting heights[i] using p-squared formula
if(this->heights[i - 1] < h && h < this->heights[i + 1])
{
this->heights[i] = h;
}
else
{
// use linear formula
if(d > 0)
{
this->heights[i] += hp;
}
if(d < 0)
{
this->heights[i] -= hm;
}
}
this->actual_positions[i] += sign_d;
}
}
}
}
result_type result(dont_care) const
{
// for i in [1,probabilities.size()], return heights[i * 2]
detail::times2_iterator idx_begin = detail::make_times2_iterator(1);
detail::times2_iterator idx_end = detail::make_times2_iterator(this->probabilities.size() + 1);
return result_type(
make_permutation_iterator(this->heights.begin(), idx_begin)
, make_permutation_iterator(this->heights.begin(), idx_end)
);
}
public:
// make this accumulator serializeable
// TODO: do we need to split to load/save and verify that the parameters did not change?
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & probabilities;
ar & heights;
ar & actual_positions;
ar & desired_positions;
ar & positions_increments;
}
private:
array_type probabilities; // the quantile probabilities
array_type heights; // q_i
array_type actual_positions; // n_i
array_type desired_positions; // d_i
array_type positions_increments; // f_i
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::extended_p_square
//
namespace tag
{
struct extended_p_square
: depends_on<count>
, extended_p_square_probabilities
{
typedef accumulators::impl::extended_p_square_impl<mpl::_1> impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::extended_p_square::probabilities named parameter
static boost::parameter::keyword<tag::probabilities> const probabilities;
#endif
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::extended_p_square
//
namespace extract
{
extractor<tag::extended_p_square> const extended_p_square = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(extended_p_square)
}
using extract::extended_p_square;
// So that extended_p_square can be automatically substituted with
// weighted_extended_p_square when the weight parameter is non-void
template<>
struct as_weighted_feature<tag::extended_p_square>
{
typedef tag::weighted_extended_p_square type;
};
template<>
struct feature_of<tag::weighted_extended_p_square>
: feature_of<tag::extended_p_square>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,332 @@
///////////////////////////////////////////////////////////////////////////////
// extended_p_square_quantile.hpp
//
// Copyright 2005 Daniel Egloff. 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_ACCUMULATORS_STATISTICS_EXTENDED_SINGLE_QUANTILE_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_EXTENDED_SINGLE_QUANTILE_HPP_DE_01_01_2006
#include <vector>
#include <functional>
#include <boost/throw_exception.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
#include <boost/accumulators/statistics/extended_p_square.hpp>
#include <boost/accumulators/statistics/weighted_extended_p_square.hpp>
#include <boost/accumulators/statistics/times2_iterator.hpp>
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// extended_p_square_quantile_impl
// single quantile estimation
/**
@brief Quantile estimation using the extended \f$P^2\f$ algorithm for weighted and unweighted samples
Uses the quantile estimates calculated by the extended \f$P^2\f$ algorithm to compute
intermediate quantile estimates by means of quadratic interpolation.
@param quantile_probability The probability of the quantile to be estimated.
*/
template<typename Sample, typename Impl1, typename Impl2> // Impl1: weighted/unweighted // Impl2: linear/quadratic
struct extended_p_square_quantile_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
typedef std::vector<float_type> array_type;
typedef iterator_range<
detail::lvalue_index_iterator<
permutation_iterator<
typename array_type::const_iterator
, detail::times2_iterator
>
>
> range_type;
// for boost::result_of
typedef float_type result_type;
template<typename Args>
extended_p_square_quantile_impl(Args const &args)
: probabilities(
boost::begin(args[extended_p_square_probabilities])
, boost::end(args[extended_p_square_probabilities])
)
, probability()
{
}
template<typename Args>
result_type result(Args const &args) const
{
typedef
typename mpl::if_<
is_same<Impl1, weighted>
, tag::weighted_extended_p_square
, tag::extended_p_square
>::type
extended_p_square_tag;
extractor<extended_p_square_tag> const some_extended_p_square = {};
array_type heights(some_extended_p_square(args).size());
std::copy(some_extended_p_square(args).begin(), some_extended_p_square(args).end(), heights.begin());
this->probability = args[quantile_probability];
typename array_type::const_iterator iter_probs = std::lower_bound(this->probabilities.begin(), this->probabilities.end(), this->probability);
std::size_t dist = std::distance(this->probabilities.begin(), iter_probs);
typename array_type::const_iterator iter_heights = heights.begin() + dist;
// If this->probability is not in a valid range return NaN or throw exception
if (this->probability < *this->probabilities.begin() || this->probability > *(this->probabilities.end() - 1))
{
if (std::numeric_limits<result_type>::has_quiet_NaN)
{
return std::numeric_limits<result_type>::quiet_NaN();
}
else
{
std::ostringstream msg;
msg << "probability = " << this->probability << " is not in valid range (";
msg << *this->probabilities.begin() << ", " << *(this->probabilities.end() - 1) << ")";
boost::throw_exception(std::runtime_error(msg.str()));
return Sample(0);
}
}
if (*iter_probs == this->probability)
{
return heights[dist];
}
else
{
result_type res;
if (is_same<Impl2, linear>::value)
{
/////////////////////////////////////////////////////////////////////////////////
// LINEAR INTERPOLATION
//
float_type p1 = *iter_probs;
float_type p0 = *(iter_probs - 1);
float_type h1 = *iter_heights;
float_type h0 = *(iter_heights - 1);
float_type a = numeric::fdiv(h1 - h0, p1 - p0);
float_type b = h1 - p1 * a;
res = a * this->probability + b;
}
else
{
/////////////////////////////////////////////////////////////////////////////////
// QUADRATIC INTERPOLATION
//
float_type p0, p1, p2;
float_type h0, h1, h2;
if ( (dist == 1 || *iter_probs - this->probability <= this->probability - *(iter_probs - 1) ) && dist != this->probabilities.size() - 1 )
{
p0 = *(iter_probs - 1);
p1 = *iter_probs;
p2 = *(iter_probs + 1);
h0 = *(iter_heights - 1);
h1 = *iter_heights;
h2 = *(iter_heights + 1);
}
else
{
p0 = *(iter_probs - 2);
p1 = *(iter_probs - 1);
p2 = *iter_probs;
h0 = *(iter_heights - 2);
h1 = *(iter_heights - 1);
h2 = *iter_heights;
}
float_type hp21 = numeric::fdiv(h2 - h1, p2 - p1);
float_type hp10 = numeric::fdiv(h1 - h0, p1 - p0);
float_type p21 = numeric::fdiv(p2 * p2 - p1 * p1, p2 - p1);
float_type p10 = numeric::fdiv(p1 * p1 - p0 * p0, p1 - p0);
float_type a = numeric::fdiv(hp21 - hp10, p21 - p10);
float_type b = hp21 - a * p21;
float_type c = h2 - a * p2 * p2 - b * p2;
res = a * this->probability * this-> probability + b * this->probability + c;
}
return res;
}
}
public:
// make this accumulator serializeable
// TODO: do we need to split to load/save and verify that the parameters did not change?
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & probabilities;
ar & probability;
}
private:
array_type probabilities;
mutable float_type probability;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::extended_p_square_quantile
//
namespace tag
{
struct extended_p_square_quantile
: depends_on<extended_p_square>
{
typedef accumulators::impl::extended_p_square_quantile_impl<mpl::_1, unweighted, linear> impl;
};
struct extended_p_square_quantile_quadratic
: depends_on<extended_p_square>
{
typedef accumulators::impl::extended_p_square_quantile_impl<mpl::_1, unweighted, quadratic> impl;
};
struct weighted_extended_p_square_quantile
: depends_on<weighted_extended_p_square>
{
typedef accumulators::impl::extended_p_square_quantile_impl<mpl::_1, weighted, linear> impl;
};
struct weighted_extended_p_square_quantile_quadratic
: depends_on<weighted_extended_p_square>
{
typedef accumulators::impl::extended_p_square_quantile_impl<mpl::_1, weighted, quadratic> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::extended_p_square_quantile
// extract::weighted_extended_p_square_quantile
//
namespace extract
{
extractor<tag::extended_p_square_quantile> const extended_p_square_quantile = {};
extractor<tag::extended_p_square_quantile_quadratic> const extended_p_square_quantile_quadratic = {};
extractor<tag::weighted_extended_p_square_quantile> const weighted_extended_p_square_quantile = {};
extractor<tag::weighted_extended_p_square_quantile_quadratic> const weighted_extended_p_square_quantile_quadratic = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(extended_p_square_quantile)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(extended_p_square_quantile_quadratic)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_extended_p_square_quantile)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_extended_p_square_quantile_quadratic)
}
using extract::extended_p_square_quantile;
using extract::extended_p_square_quantile_quadratic;
using extract::weighted_extended_p_square_quantile;
using extract::weighted_extended_p_square_quantile_quadratic;
// extended_p_square_quantile(linear) -> extended_p_square_quantile
template<>
struct as_feature<tag::extended_p_square_quantile(linear)>
{
typedef tag::extended_p_square_quantile type;
};
// extended_p_square_quantile(quadratic) -> extended_p_square_quantile_quadratic
template<>
struct as_feature<tag::extended_p_square_quantile(quadratic)>
{
typedef tag::extended_p_square_quantile_quadratic type;
};
// weighted_extended_p_square_quantile(linear) -> weighted_extended_p_square_quantile
template<>
struct as_feature<tag::weighted_extended_p_square_quantile(linear)>
{
typedef tag::weighted_extended_p_square_quantile type;
};
// weighted_extended_p_square_quantile(quadratic) -> weighted_extended_p_square_quantile_quadratic
template<>
struct as_feature<tag::weighted_extended_p_square_quantile(quadratic)>
{
typedef tag::weighted_extended_p_square_quantile_quadratic type;
};
// for the purposes of feature-based dependency resolution,
// extended_p_square_quantile and weighted_extended_p_square_quantile
// provide the same feature as quantile
template<>
struct feature_of<tag::extended_p_square_quantile>
: feature_of<tag::quantile>
{
};
template<>
struct feature_of<tag::extended_p_square_quantile_quadratic>
: feature_of<tag::quantile>
{
};
// So that extended_p_square_quantile can be automatically substituted with
// weighted_extended_p_square_quantile when the weight parameter is non-void
template<>
struct as_weighted_feature<tag::extended_p_square_quantile>
{
typedef tag::weighted_extended_p_square_quantile type;
};
template<>
struct feature_of<tag::weighted_extended_p_square_quantile>
: feature_of<tag::extended_p_square_quantile>
{
};
// So that extended_p_square_quantile_quadratic can be automatically substituted with
// weighted_extended_p_square_quantile_quadratic when the weight parameter is non-void
template<>
struct as_weighted_feature<tag::extended_p_square_quantile_quadratic>
{
typedef tag::weighted_extended_p_square_quantile_quadratic type;
};
template<>
struct feature_of<tag::weighted_extended_p_square_quantile_quadratic>
: feature_of<tag::extended_p_square_quantile_quadratic>
{
};
}} // namespace boost::accumulators
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,116 @@
///////////////////////////////////////////////////////////////////////////////
// kurtosis.hpp
//
// Copyright 2006 Olivier Gygi, Daniel Egloff. 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_ACCUMULATORS_STATISTICS_KURTOSIS_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_KURTOSIS_HPP_EAN_28_10_2005
#include <limits>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// kurtosis_impl
/**
@brief Kurtosis estimation
The kurtosis of a sample distribution is defined as the ratio of the 4th central moment and the square of the 2nd central
moment (the variance) of the samples, minus 3. The term \f$ -3 \f$ is added in order to ensure that the normal distribution
has zero kurtosis. The kurtosis can also be expressed by the simple moments:
\f[
\hat{g}_2 =
\frac
{\widehat{m}_n^{(4)}-4\widehat{m}_n^{(3)}\hat{\mu}_n+6\widehat{m}_n^{(2)}\hat{\mu}_n^2-3\hat{\mu}_n^4}
{\left(\widehat{m}_n^{(2)} - \hat{\mu}_n^{2}\right)^2} - 3,
\f]
where \f$ \widehat{m}_n^{(i)} \f$ are the \f$ i \f$-th moment and \f$ \hat{\mu}_n \f$ the mean (first moment) of the
\f$ n \f$ samples.
*/
template<typename Sample>
struct kurtosis_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, Sample>::result_type result_type;
kurtosis_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
return numeric::fdiv(
accumulators::moment<4>(args)
- 4. * accumulators::moment<3>(args) * mean(args)
+ 6. * accumulators::moment<2>(args) * mean(args) * mean(args)
- 3. * mean(args) * mean(args) * mean(args) * mean(args)
, ( accumulators::moment<2>(args) - mean(args) * mean(args) )
* ( accumulators::moment<2>(args) - mean(args) * mean(args) )
) - 3.;
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::kurtosis
//
namespace tag
{
struct kurtosis
: depends_on<mean, moment<2>, moment<3>, moment<4> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::kurtosis_impl<mpl::_1> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::kurtosis
//
namespace extract
{
extractor<tag::kurtosis> const kurtosis = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(kurtosis)
}
using extract::kurtosis;
// So that kurtosis can be automatically substituted with
// weighted_kurtosis when the weight parameter is non-void
template<>
struct as_weighted_feature<tag::kurtosis>
{
typedef tag::weighted_kurtosis type;
};
template<>
struct feature_of<tag::weighted_kurtosis>
: feature_of<tag::kurtosis>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,92 @@
///////////////////////////////////////////////////////////////////////////////
// max.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_MAX_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_MAX_HPP_EAN_28_10_2005
#include <limits>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// max_impl
template<typename Sample>
struct max_impl
: accumulator_base
{
// for boost::result_of
typedef Sample result_type;
template<typename Args>
max_impl(Args const &args)
: max_(numeric::as_min(args[sample | Sample()]))
{
}
template<typename Args>
void operator ()(Args const &args)
{
numeric::max_assign(this->max_, args[sample]);
}
result_type result(dont_care) const
{
return this->max_;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */)
{
ar & max_;
}
private:
Sample max_;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::max
//
namespace tag
{
struct max
: depends_on<>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::max_impl<mpl::_1> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::max
//
namespace extract
{
extractor<tag::max> const max = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(max)
}
using extract::max;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,308 @@
///////////////////////////////////////////////////////////////////////////////
// mean.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_MEAN_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_MEAN_HPP_EAN_28_10_2005
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/sum.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// mean_impl
// lazy, by default
template<typename Sample, typename SumFeature>
struct mean_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
mean_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
extractor<SumFeature> sum;
return numeric::fdiv(sum(args), count(args));
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & /* ar */, const unsigned int /* file_version */) {}
};
template<typename Sample, typename Tag>
struct immediate_mean_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
template<typename Args>
immediate_mean_impl(Args const &args)
: mean(numeric::fdiv(args[sample | Sample()], numeric::one<std::size_t>::value))
{
}
template<typename Args>
void operator ()(Args const &args)
{
std::size_t cnt = count(args);
this->mean = numeric::fdiv(
(this->mean * (cnt - 1)) + args[parameter::keyword<Tag>::get()]
, cnt
);
}
result_type result(dont_care) const
{
return this->mean;
}
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */)
{
ar & mean;
}
private:
result_type mean;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::mean
// tag::immediate_mean
// tag::mean_of_weights
// tag::immediate_mean_of_weights
// tag::mean_of_variates
// tag::immediate_mean_of_variates
//
namespace tag
{
struct mean
: depends_on<count, sum>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::mean_impl<mpl::_1, sum> impl;
};
struct immediate_mean
: depends_on<count>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::immediate_mean_impl<mpl::_1, tag::sample> impl;
};
struct mean_of_weights
: depends_on<count, sum_of_weights>
{
typedef mpl::true_ is_weight_accumulator;
/// INTERNAL ONLY
///
typedef accumulators::impl::mean_impl<mpl::_2, sum_of_weights> impl;
};
struct immediate_mean_of_weights
: depends_on<count>
{
typedef mpl::true_ is_weight_accumulator;
/// INTERNAL ONLY
///
typedef accumulators::impl::immediate_mean_impl<mpl::_2, tag::weight> impl;
};
template<typename VariateType, typename VariateTag>
struct mean_of_variates
: depends_on<count, sum_of_variates<VariateType, VariateTag> >
{
/// INTERNAL ONLY
///
typedef mpl::always<accumulators::impl::mean_impl<VariateType, sum_of_variates<VariateType, VariateTag> > > impl;
};
template<typename VariateType, typename VariateTag>
struct immediate_mean_of_variates
: depends_on<count>
{
/// INTERNAL ONLY
///
typedef mpl::always<accumulators::impl::immediate_mean_impl<VariateType, VariateTag> > impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::mean
// extract::mean_of_weights
// extract::mean_of_variates
//
namespace extract
{
extractor<tag::mean> const mean = {};
extractor<tag::mean_of_weights> const mean_of_weights = {};
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, mean_of_variates, (typename)(typename))
BOOST_ACCUMULATORS_IGNORE_GLOBAL(mean)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(mean_of_weights)
}
using extract::mean;
using extract::mean_of_weights;
using extract::mean_of_variates;
// mean(lazy) -> mean
template<>
struct as_feature<tag::mean(lazy)>
{
typedef tag::mean type;
};
// mean(immediate) -> immediate_mean
template<>
struct as_feature<tag::mean(immediate)>
{
typedef tag::immediate_mean type;
};
// mean_of_weights(lazy) -> mean_of_weights
template<>
struct as_feature<tag::mean_of_weights(lazy)>
{
typedef tag::mean_of_weights type;
};
// mean_of_weights(immediate) -> immediate_mean_of_weights
template<>
struct as_feature<tag::mean_of_weights(immediate)>
{
typedef tag::immediate_mean_of_weights type;
};
// mean_of_variates<VariateType, VariateTag>(lazy) -> mean_of_variates<VariateType, VariateTag>
template<typename VariateType, typename VariateTag>
struct as_feature<tag::mean_of_variates<VariateType, VariateTag>(lazy)>
{
typedef tag::mean_of_variates<VariateType, VariateTag> type;
};
// mean_of_variates<VariateType, VariateTag>(immediate) -> immediate_mean_of_variates<VariateType, VariateTag>
template<typename VariateType, typename VariateTag>
struct as_feature<tag::mean_of_variates<VariateType, VariateTag>(immediate)>
{
typedef tag::immediate_mean_of_variates<VariateType, VariateTag> type;
};
// for the purposes of feature-based dependency resolution,
// immediate_mean provides the same feature as mean
template<>
struct feature_of<tag::immediate_mean>
: feature_of<tag::mean>
{
};
// for the purposes of feature-based dependency resolution,
// immediate_mean provides the same feature as mean
template<>
struct feature_of<tag::immediate_mean_of_weights>
: feature_of<tag::mean_of_weights>
{
};
// for the purposes of feature-based dependency resolution,
// immediate_mean provides the same feature as mean
template<typename VariateType, typename VariateTag>
struct feature_of<tag::immediate_mean_of_variates<VariateType, VariateTag> >
: feature_of<tag::mean_of_variates<VariateType, VariateTag> >
{
};
// So that mean can be automatically substituted with
// weighted_mean when the weight parameter is non-void.
template<>
struct as_weighted_feature<tag::mean>
{
typedef tag::weighted_mean type;
};
template<>
struct feature_of<tag::weighted_mean>
: feature_of<tag::mean>
{};
// So that immediate_mean can be automatically substituted with
// immediate_weighted_mean when the weight parameter is non-void.
template<>
struct as_weighted_feature<tag::immediate_mean>
{
typedef tag::immediate_weighted_mean type;
};
template<>
struct feature_of<tag::immediate_weighted_mean>
: feature_of<tag::immediate_mean>
{};
// So that mean_of_weights<> can be automatically substituted with
// weighted_mean_of_variates<> when the weight parameter is non-void.
template<typename VariateType, typename VariateTag>
struct as_weighted_feature<tag::mean_of_variates<VariateType, VariateTag> >
{
typedef tag::weighted_mean_of_variates<VariateType, VariateTag> type;
};
template<typename VariateType, typename VariateTag>
struct feature_of<tag::weighted_mean_of_variates<VariateType, VariateTag> >
: feature_of<tag::mean_of_variates<VariateType, VariateTag> >
{
};
// So that immediate_mean_of_weights<> can be automatically substituted with
// immediate_weighted_mean_of_variates<> when the weight parameter is non-void.
template<typename VariateType, typename VariateTag>
struct as_weighted_feature<tag::immediate_mean_of_variates<VariateType, VariateTag> >
{
typedef tag::immediate_weighted_mean_of_variates<VariateType, VariateTag> type;
};
template<typename VariateType, typename VariateTag>
struct feature_of<tag::immediate_weighted_mean_of_variates<VariateType, VariateTag> >
: feature_of<tag::immediate_mean_of_variates<VariateType, VariateTag> >
{
};
////////////////////////////////////////////////////////////////////////////
//// droppable_accumulator<mean_impl>
//// need to specialize droppable lazy mean to cache the result at the
//// point the accumulator is dropped.
///// INTERNAL ONLY
/////
//template<typename Sample, typename SumFeature>
//struct droppable_accumulator<impl::mean_impl<Sample, SumFeature> >
// : droppable_accumulator_base<
// with_cached_result<impl::mean_impl<Sample, SumFeature> >
// >
//{
// template<typename Args>
// droppable_accumulator(Args const &args)
// : droppable_accumulator::base(args)
// {
// }
//};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,324 @@
///////////////////////////////////////////////////////////////////////////////
// median.hpp
//
// Copyright 2006 Eric Niebler, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_MEDIAN_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_MEDIAN_HPP_EAN_28_10_2005
#include <boost/mpl/placeholders.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/p_square_quantile.hpp>
#include <boost/accumulators/statistics/density.hpp>
#include <boost/accumulators/statistics/p_square_cumul_dist.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// median_impl
//
/**
@brief Median estimation based on the \f$P^2\f$ quantile estimator
The \f$P^2\f$ algorithm is invoked with a quantile probability of 0.5.
*/
template<typename Sample>
struct median_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
median_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
return p_square_quantile_for_median(args);
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {}
};
///////////////////////////////////////////////////////////////////////////////
// with_density_median_impl
//
/**
@brief Median estimation based on the density estimator
The algorithm determines the bin in which the \f$0.5*cnt\f$-th sample lies, \f$cnt\f$ being
the total number of samples. It returns the approximate horizontal position of this sample,
based on a linear interpolation inside the bin.
*/
template<typename Sample>
struct with_density_median_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
typedef iterator_range<typename histogram_type::iterator> range_type;
// for boost::result_of
typedef float_type result_type;
template<typename Args>
with_density_median_impl(Args const &args)
: sum(numeric::fdiv(args[sample | Sample()], (std::size_t)1))
, is_dirty(true)
{
}
void operator ()(dont_care)
{
this->is_dirty = true;
}
template<typename Args>
result_type result(Args const &args) const
{
if (this->is_dirty)
{
this->is_dirty = false;
std::size_t cnt = count(args);
range_type histogram = density(args);
typename range_type::iterator it = histogram.begin();
while (this->sum < 0.5 * cnt)
{
this->sum += it->second * cnt;
++it;
}
--it;
float_type over = numeric::fdiv(this->sum - 0.5 * cnt, it->second * cnt);
this->median = it->first * over + (it + 1)->first * (1. - over);
}
return this->median;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & sum;
ar & is_dirty;
ar & median;
}
private:
mutable float_type sum;
mutable bool is_dirty;
mutable float_type median;
};
///////////////////////////////////////////////////////////////////////////////
// with_p_square_cumulative_distribution_median_impl
//
/**
@brief Median estimation based on the \f$P^2\f$ cumulative distribution estimator
The algorithm determines the first (leftmost) bin with a height exceeding 0.5. It
returns the approximate horizontal position of where the cumulative distribution
equals 0.5, based on a linear interpolation inside the bin.
*/
template<typename Sample>
struct with_p_square_cumulative_distribution_median_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
typedef iterator_range<typename histogram_type::iterator> range_type;
// for boost::result_of
typedef float_type result_type;
with_p_square_cumulative_distribution_median_impl(dont_care)
: is_dirty(true)
{
}
void operator ()(dont_care)
{
this->is_dirty = true;
}
template<typename Args>
result_type result(Args const &args) const
{
if (this->is_dirty)
{
this->is_dirty = false;
range_type histogram = p_square_cumulative_distribution(args);
typename range_type::iterator it = histogram.begin();
while (it->second < 0.5)
{
++it;
}
float_type over = numeric::fdiv(it->second - 0.5, it->second - (it - 1)->second);
this->median = it->first * over + (it + 1)->first * ( 1. - over );
}
return this->median;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & is_dirty;
ar & median;
}
private:
mutable bool is_dirty;
mutable float_type median;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::median
// tag::with_densisty_median
// tag::with_p_square_cumulative_distribution_median
//
namespace tag
{
struct median
: depends_on<p_square_quantile_for_median>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::median_impl<mpl::_1> impl;
};
struct with_density_median
: depends_on<count, density>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::with_density_median_impl<mpl::_1> impl;
};
struct with_p_square_cumulative_distribution_median
: depends_on<p_square_cumulative_distribution>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::with_p_square_cumulative_distribution_median_impl<mpl::_1> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::median
// extract::with_density_median
// extract::with_p_square_cumulative_distribution_median
//
namespace extract
{
extractor<tag::median> const median = {};
extractor<tag::with_density_median> const with_density_median = {};
extractor<tag::with_p_square_cumulative_distribution_median> const with_p_square_cumulative_distribution_median = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(median)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(with_density_median)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(with_p_square_cumulative_distribution_median)
}
using extract::median;
using extract::with_density_median;
using extract::with_p_square_cumulative_distribution_median;
// median(with_p_square_quantile) -> median
template<>
struct as_feature<tag::median(with_p_square_quantile)>
{
typedef tag::median type;
};
// median(with_density) -> with_density_median
template<>
struct as_feature<tag::median(with_density)>
{
typedef tag::with_density_median type;
};
// median(with_p_square_cumulative_distribution) -> with_p_square_cumulative_distribution_median
template<>
struct as_feature<tag::median(with_p_square_cumulative_distribution)>
{
typedef tag::with_p_square_cumulative_distribution_median type;
};
// for the purposes of feature-based dependency resolution,
// with_density_median and with_p_square_cumulative_distribution_median
// provide the same feature as median
template<>
struct feature_of<tag::with_density_median>
: feature_of<tag::median>
{
};
template<>
struct feature_of<tag::with_p_square_cumulative_distribution_median>
: feature_of<tag::median>
{
};
// So that median can be automatically substituted with
// weighted_median when the weight parameter is non-void.
template<>
struct as_weighted_feature<tag::median>
{
typedef tag::weighted_median type;
};
template<>
struct feature_of<tag::weighted_median>
: feature_of<tag::median>
{
};
// So that with_density_median can be automatically substituted with
// with_density_weighted_median when the weight parameter is non-void.
template<>
struct as_weighted_feature<tag::with_density_median>
{
typedef tag::with_density_weighted_median type;
};
template<>
struct feature_of<tag::with_density_weighted_median>
: feature_of<tag::with_density_median>
{
};
// So that with_p_square_cumulative_distribution_median can be automatically substituted with
// with_p_square_cumulative_distribution_weighted_median when the weight parameter is non-void.
template<>
struct as_weighted_feature<tag::with_p_square_cumulative_distribution_median>
{
typedef tag::with_p_square_cumulative_distribution_weighted_median type;
};
template<>
struct feature_of<tag::with_p_square_cumulative_distribution_weighted_median>
: feature_of<tag::with_p_square_cumulative_distribution_median>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,92 @@
///////////////////////////////////////////////////////////////////////////////
// min.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_MIN_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_MIN_HPP_EAN_28_10_2005
#include <limits>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// min_impl
template<typename Sample>
struct min_impl
: accumulator_base
{
// for boost::result_of
typedef Sample result_type;
template<typename Args>
min_impl(Args const &args)
: min_(numeric::as_max(args[sample | Sample()]))
{
}
template<typename Args>
void operator ()(Args const &args)
{
numeric::min_assign(this->min_, args[sample]);
}
result_type result(dont_care) const
{
return this->min_;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */)
{
ar & min_;
}
private:
Sample min_;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::min
//
namespace tag
{
struct min
: depends_on<>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::min_impl<mpl::_1> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::min
//
namespace extract
{
extractor<tag::min> const min = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(min)
}
using extract::min;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,132 @@
///////////////////////////////////////////////////////////////////////////////
// moment.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_MOMENT_HPP_EAN_15_11_2005
#define BOOST_ACCUMULATORS_STATISTICS_MOMENT_HPP_EAN_15_11_2005
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
namespace boost { namespace numeric
{
/// INTERNAL ONLY
///
template<typename T>
T const &pow(T const &x, mpl::int_<1>)
{
return x;
}
/// INTERNAL ONLY
///
template<typename T, int N>
T pow(T const &x, mpl::int_<N>)
{
using namespace operators;
T y = numeric::pow(x, mpl::int_<N/2>());
T z = y * y;
return (N % 2) ? (z * x) : z;
}
}}
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// moment_impl
template<typename N, typename Sample>
struct moment_impl
: accumulator_base // TODO: also depends_on sum of powers
{
BOOST_MPL_ASSERT_RELATION(N::value, >, 0);
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
template<typename Args>
moment_impl(Args const &args)
: sum(args[sample | Sample()])
{
}
template<typename Args>
void operator ()(Args const &args)
{
this->sum += numeric::pow(args[sample], N());
}
template<typename Args>
result_type result(Args const &args) const
{
return numeric::fdiv(this->sum, count(args));
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */)
{
ar & sum;
}
private:
Sample sum;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::moment
//
namespace tag
{
template<int N>
struct moment
: depends_on<count>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::moment_impl<mpl::int_<N>, mpl::_1> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::moment
//
namespace extract
{
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, moment, (int))
}
using extract::moment;
// So that moment<N> can be automatically substituted with
// weighted_moment<N> when the weight parameter is non-void
template<int N>
struct as_weighted_feature<tag::moment<N> >
{
typedef tag::weighted_moment<N> type;
};
template<int N>
struct feature_of<tag::weighted_moment<N> >
: feature_of<tag::moment<N> >
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,279 @@
///////////////////////////////////////////////////////////////////////////////
// p_square_cumulative_distribution.hpp
//
// Copyright 2005 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_P_SQUARE_CUMUL_DIST_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_CUMUL_DIST_HPP_DE_01_01_2006
#include <vector>
#include <functional>
#include <boost/parameter/keyword.hpp>
#include <boost/range.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/utility.hpp>
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////////
// num_cells named parameter
//
BOOST_PARAMETER_NESTED_KEYWORD(tag, p_square_cumulative_distribution_num_cells, num_cells)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(p_square_cumulative_distribution_num_cells)
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// p_square_cumulative_distribution_impl
// cumulative_distribution calculation (as histogram)
/**
@brief Histogram calculation of the cumulative distribution with the \f$P^2\f$ algorithm
A histogram of the sample cumulative distribution is computed dynamically without storing samples
based on the \f$ P^2 \f$ algorithm. The returned histogram has a specifiable amount (num_cells)
equiprobable (and not equal-sized) cells.
For further details, see
R. Jain and I. Chlamtac, The P^2 algorithm for dynamic calculation of quantiles and
histograms without storing observations, Communications of the ACM,
Volume 28 (October), Number 10, 1985, p. 1076-1085.
@param p_square_cumulative_distribution_num_cells.
*/
template<typename Sample>
struct p_square_cumulative_distribution_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
typedef std::vector<float_type> array_type;
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
// for boost::result_of
typedef iterator_range<typename histogram_type::iterator> result_type;
template<typename Args>
p_square_cumulative_distribution_impl(Args const &args)
: num_cells(args[p_square_cumulative_distribution_num_cells])
, heights(num_cells + 1)
, actual_positions(num_cells + 1)
, desired_positions(num_cells + 1)
, positions_increments(num_cells + 1)
, histogram(num_cells + 1)
, is_dirty(true)
{
std::size_t b = this->num_cells;
for (std::size_t i = 0; i < b + 1; ++i)
{
this->actual_positions[i] = i + 1.;
this->desired_positions[i] = i + 1.;
this->positions_increments[i] = numeric::fdiv(i, b);
}
}
template<typename Args>
void operator ()(Args const &args)
{
this->is_dirty = true;
std::size_t cnt = count(args);
std::size_t sample_cell = 1; // k
std::size_t b = this->num_cells;
// accumulate num_cells + 1 first samples
if (cnt <= b + 1)
{
this->heights[cnt - 1] = args[sample];
// complete the initialization of heights by sorting
if (cnt == b + 1)
{
std::sort(this->heights.begin(), this->heights.end());
}
}
else
{
// find cell k such that heights[k-1] <= args[sample] < heights[k] and adjust extreme values
if (args[sample] < this->heights[0])
{
this->heights[0] = args[sample];
sample_cell = 1;
}
else if (this->heights[b] <= args[sample])
{
this->heights[b] = args[sample];
sample_cell = b;
}
else
{
typename array_type::iterator it;
it = std::upper_bound(
this->heights.begin()
, this->heights.end()
, args[sample]
);
sample_cell = std::distance(this->heights.begin(), it);
}
// increment positions of markers above sample_cell
for (std::size_t i = sample_cell; i < b + 1; ++i)
{
++this->actual_positions[i];
}
// update desired position of markers 2 to num_cells + 1
// (desired position of first marker is always 1)
for (std::size_t i = 1; i < b + 1; ++i)
{
this->desired_positions[i] += this->positions_increments[i];
}
// adjust heights of markers 2 to num_cells if necessary
for (std::size_t i = 1; i < b; ++i)
{
// offset to desire position
float_type d = this->desired_positions[i] - this->actual_positions[i];
// offset to next position
float_type dp = this->actual_positions[i + 1] - this->actual_positions[i];
// offset to previous position
float_type dm = this->actual_positions[i - 1] - this->actual_positions[i];
// height ds
float_type hp = (this->heights[i + 1] - this->heights[i]) / dp;
float_type hm = (this->heights[i - 1] - this->heights[i]) / dm;
if ( ( d >= 1. && dp > 1. ) || ( d <= -1. && dm < -1. ) )
{
short sign_d = static_cast<short>(d / std::abs(d));
// try adjusting heights[i] using p-squared formula
float_type h = this->heights[i] + sign_d / (dp - dm) * ( (sign_d - dm) * hp + (dp - sign_d) * hm );
if ( this->heights[i - 1] < h && h < this->heights[i + 1] )
{
this->heights[i] = h;
}
else
{
// use linear formula
if (d>0)
{
this->heights[i] += hp;
}
if (d<0)
{
this->heights[i] -= hm;
}
}
this->actual_positions[i] += sign_d;
}
}
}
}
template<typename Args>
result_type result(Args const &args) const
{
if (this->is_dirty)
{
this->is_dirty = false;
// creates a vector of std::pair where each pair i holds
// the values heights[i] (x-axis of histogram) and
// actual_positions[i] / cnt (y-axis of histogram)
std::size_t cnt = count(args);
for (std::size_t i = 0; i < this->histogram.size(); ++i)
{
this->histogram[i] = std::make_pair(this->heights[i], numeric::fdiv(this->actual_positions[i], cnt));
}
}
//return histogram;
return make_iterator_range(this->histogram);
}
// make this accumulator serializeable
// TODO split to save/load and check on parameters provided in ctor
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & num_cells;
ar & heights;
ar & actual_positions;
ar & desired_positions;
ar & positions_increments;
ar & histogram;
ar & is_dirty;
}
private:
std::size_t num_cells; // number of cells b
array_type heights; // q_i
array_type actual_positions; // n_i
array_type desired_positions; // n'_i
array_type positions_increments; // dn'_i
mutable histogram_type histogram; // histogram
mutable bool is_dirty;
};
} // namespace detail
///////////////////////////////////////////////////////////////////////////////
// tag::p_square_cumulative_distribution
//
namespace tag
{
struct p_square_cumulative_distribution
: depends_on<count>
, p_square_cumulative_distribution_num_cells
{
/// INTERNAL ONLY
///
typedef accumulators::impl::p_square_cumulative_distribution_impl<mpl::_1> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::p_square_cumulative_distribution
//
namespace extract
{
extractor<tag::p_square_cumulative_distribution> const p_square_cumulative_distribution = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(p_square_cumulative_distribution)
}
using extract::p_square_cumulative_distribution;
// So that p_square_cumulative_distribution can be automatically substituted with
// weighted_p_square_cumulative_distribution when the weight parameter is non-void
template<>
struct as_weighted_feature<tag::p_square_cumulative_distribution>
{
typedef tag::weighted_p_square_cumulative_distribution type;
};
template<>
struct feature_of<tag::weighted_p_square_cumulative_distribution>
: feature_of<tag::p_square_cumulative_distribution>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,19 @@
///////////////////////////////////////////////////////////////////////////////
// p_square_cumulative_distribution.hpp
//
// Copyright 2012 Eric Niebler. 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_ACCUMULATORS_STATISTICS_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
#define BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
#if defined(_MSC_VER) || defined(__BORLANDC__) && !defined(__clang__) || defined(__DMC__)
# pragma message ("Warning: This header is deprecated. Please use: boost/accumulators/statistics/p_square_cumul_dist.hpp")
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__) || defined(__BORLANDC__)
# warning "This header is deprecated. Please use: boost/accumulators/statistics/p_square_cumul_dist.hpp"
#endif
#include <boost/accumulators/statistics/p_square_cumul_dist.hpp>
#endif
@@ -0,0 +1,271 @@
///////////////////////////////////////////////////////////////////////////////
// p_square_quantile.hpp
//
// Copyright 2005 Daniel Egloff. 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_ACCUMULATORS_STATISTICS_P_SQUARE_QUANTILE_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_P_SQUARE_QUANTILE_HPP_DE_01_01_2006
#include <cmath>
#include <functional>
#include <boost/array.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
#include <boost/serialization/boost_array.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// p_square_quantile_impl
// single quantile estimation
/**
@brief Single quantile estimation with the \f$P^2\f$ algorithm
The \f$P^2\f$ algorithm estimates a quantile dynamically without storing samples. Instead of
storing the whole sample cumulative distribution, only five points (markers) are stored. The heights
of these markers are the minimum and the maximum of the samples and the current estimates of the
\f$(p/2)\f$-, \f$p\f$- and \f$(1+p)/2\f$-quantiles. Their positions are equal to the number
of samples that are smaller or equal to the markers. Each time a new samples is recorded, the
positions of the markers are updated and if necessary their heights are adjusted using a piecewise-
parabolic formula.
For further details, see
R. Jain and I. Chlamtac, The P^2 algorithm for dynamic calculation of quantiles and
histograms without storing observations, Communications of the ACM,
Volume 28 (October), Number 10, 1985, p. 1076-1085.
@param quantile_probability
*/
template<typename Sample, typename Impl>
struct p_square_quantile_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
typedef array<float_type, 5> array_type;
// for boost::result_of
typedef float_type result_type;
template<typename Args>
p_square_quantile_impl(Args const &args)
: p(is_same<Impl, for_median>::value ? float_type(0.5) : args[quantile_probability | float_type(0.5)])
, heights()
, actual_positions()
, desired_positions()
, positions_increments()
{
for(std::size_t i = 0; i < 5; ++i)
{
this->actual_positions[i] = i + float_type(1.);
}
this->desired_positions[0] = float_type(1.);
this->desired_positions[1] = float_type(1.) + float_type(2.) * this->p;
this->desired_positions[2] = float_type(1.) + float_type(4.) * this->p;
this->desired_positions[3] = float_type(3.) + float_type(2.) * this->p;
this->desired_positions[4] = float_type(5.);
this->positions_increments[0] = float_type(0.);
this->positions_increments[1] = this->p / float_type(2.);
this->positions_increments[2] = this->p;
this->positions_increments[3] = (float_type(1.) + this->p) / float_type(2.);
this->positions_increments[4] = float_type(1.);
}
template<typename Args>
void operator ()(Args const &args)
{
std::size_t cnt = count(args);
// accumulate 5 first samples
if(cnt <= 5)
{
this->heights[cnt - 1] = args[sample];
// complete the initialization of heights by sorting
if(cnt == 5)
{
std::sort(this->heights.begin(), this->heights.end());
}
}
else
{
std::size_t sample_cell = 1; // k
// find cell k such that heights[k-1] <= args[sample] < heights[k] and adjust extreme values
if (args[sample] < this->heights[0])
{
this->heights[0] = args[sample];
sample_cell = 1;
}
else if (this->heights[4] <= args[sample])
{
this->heights[4] = args[sample];
sample_cell = 4;
}
else
{
typedef typename array_type::iterator iterator;
iterator it = std::upper_bound(
this->heights.begin()
, this->heights.end()
, args[sample]
);
sample_cell = std::distance(this->heights.begin(), it);
}
// update positions of markers above sample_cell
for(std::size_t i = sample_cell; i < 5; ++i)
{
++this->actual_positions[i];
}
// update desired positions of all markers
for(std::size_t i = 0; i < 5; ++i)
{
this->desired_positions[i] += this->positions_increments[i];
}
// adjust heights and actual positions of markers 1 to 3 if necessary
for(std::size_t i = 1; i <= 3; ++i)
{
// offset to desired positions
float_type d = this->desired_positions[i] - this->actual_positions[i];
// offset to next position
float_type dp = this->actual_positions[i + 1] - this->actual_positions[i];
// offset to previous position
float_type dm = this->actual_positions[i - 1] - this->actual_positions[i];
// height ds
float_type hp = (this->heights[i + 1] - this->heights[i]) / dp;
float_type hm = (this->heights[i - 1] - this->heights[i]) / dm;
if((d >= float_type(1.) && dp > float_type(1.)) || (d <= float_type(-1.) && dm < float_type(-1.)))
{
short sign_d = static_cast<short>(d / std::abs(d));
// try adjusting heights[i] using p-squared formula
float_type h = this->heights[i] + sign_d / (dp - dm) * ((sign_d - dm) * hp
+ (dp - sign_d) * hm);
if(this->heights[i - 1] < h && h < this->heights[i + 1])
{
this->heights[i] = h;
}
else
{
// use linear formula
if(d > float_type(0))
{
this->heights[i] += hp;
}
if(d < float_type(0))
{
this->heights[i] -= hm;
}
}
this->actual_positions[i] += sign_d;
}
}
}
}
result_type result(dont_care) const
{
return this->heights[2];
}
// make this accumulator serializeable
// TODO: do we need to split to load/save and verify that P did not change?
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & p;
ar & heights;
ar & actual_positions;
ar & desired_positions;
ar & positions_increments;
}
private:
float_type p; // the quantile probability p
array_type heights; // q_i
array_type actual_positions; // n_i
array_type desired_positions; // n'_i
array_type positions_increments; // dn'_i
};
} // namespace detail
///////////////////////////////////////////////////////////////////////////////
// tag::p_square_quantile
//
namespace tag
{
struct p_square_quantile
: depends_on<count>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::p_square_quantile_impl<mpl::_1, regular> impl;
};
struct p_square_quantile_for_median
: depends_on<count>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::p_square_quantile_impl<mpl::_1, for_median> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::p_square_quantile
// extract::p_square_quantile_for_median
//
namespace extract
{
extractor<tag::p_square_quantile> const p_square_quantile = {};
extractor<tag::p_square_quantile_for_median> const p_square_quantile_for_median = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(p_square_quantile)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(p_square_quantile_for_median)
}
using extract::p_square_quantile;
using extract::p_square_quantile_for_median;
// So that p_square_quantile can be automatically substituted with
// weighted_p_square_quantile when the weight parameter is non-void
template<>
struct as_weighted_feature<tag::p_square_quantile>
{
typedef tag::weighted_p_square_quantile type;
};
template<>
struct feature_of<tag::weighted_p_square_quantile>
: feature_of<tag::p_square_quantile>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,23 @@
///////////////////////////////////////////////////////////////////////////////
// quantile_probability.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_PARAMETERS_QUANTILE_PROBABILITY_HPP_EAN_03_11_2005
#define BOOST_ACCUMULATORS_STATISTICS_PARAMETERS_QUANTILE_PROBABILITY_HPP_EAN_03_11_2005
#include <boost/parameter/keyword.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
namespace boost { namespace accumulators
{
BOOST_PARAMETER_KEYWORD(tag, quantile_probability)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(quantile_probability)
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,434 @@
///////////////////////////////////////////////////////////////////////////////
// peaks_over_threshold.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_PEAKS_OVER_THRESHOLD_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_PEAKS_OVER_THRESHOLD_HPP_DE_01_01_2006
#include <vector>
#include <limits>
#include <numeric>
#include <functional>
#include <boost/config/no_tr1/cmath.hpp> // pow
#include <sstream> // stringstream
#include <stdexcept> // runtime_error
#include <boost/throw_exception.hpp>
#include <boost/range.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/tail.hpp>
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////////
// threshold_probability and threshold named parameters
//
BOOST_PARAMETER_NESTED_KEYWORD(tag, pot_threshold_value, threshold_value)
BOOST_PARAMETER_NESTED_KEYWORD(tag, pot_threshold_probability, threshold_probability)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(pot_threshold_value)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(pot_threshold_probability)
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// peaks_over_threshold_impl
// works with an explicit threshold value and does not depend on order statistics
/**
@brief Peaks over Threshold Method for Quantile and Tail Mean Estimation
According to the theorem of Pickands-Balkema-de Haan, the distribution function \f$F_u(x)\f$ of
the excesses \f$x\f$ over some sufficiently high threshold \f$u\f$ of a distribution function \f$F(x)\f$
may be approximated by a generalized Pareto distribution
\f[
G_{\xi,\beta}(x) =
\left\{
\begin{array}{ll}
\beta^{-1}\left(1+\frac{\xi x}{\beta}\right)^{-1/\xi-1} & \textrm{if }\xi\neq0\\
\beta^{-1}\exp\left(-\frac{x}{\beta}\right) & \textrm{if }\xi=0,
\end{array}
\right.
\f]
with suitable parameters \f$\xi\f$ and \f$\beta\f$ that can be estimated, e.g., with the method of moments, cf.
Hosking and Wallis (1987),
\f[
\begin{array}{lll}
\hat{\xi} & = & \frac{1}{2}\left[1-\frac{(\hat{\mu}-u)^2}{\hat{\sigma}^2}\right]\\
\hat{\beta} & = & \frac{\hat{\mu}-u}{2}\left[\frac{(\hat{\mu}-u)^2}{\hat{\sigma}^2}+1\right],
\end{array}
\f]
\f$\hat{\mu}\f$ and \f$\hat{\sigma}^2\f$ being the empirical mean and variance of the samples over
the threshold \f$u\f$. Equivalently, the distribution function
\f$F_u(x-u)\f$ of the exceedances \f$x-u\f$ can be approximated by
\f$G_{\xi,\beta}(x-u)=G_{\xi,\beta,u}(x)\f$. Since for \f$x\geq u\f$ the distribution function \f$F(x)\f$
can be written as
\f[
F(x) = [1 - \P(X \leq u)]F_u(x - u) + \P(X \leq u)
\f]
and the probability \f$\P(X \leq u)\f$ can be approximated by the empirical distribution function
\f$F_n(u)\f$ evaluated at \f$u\f$, an estimator of \f$F(x)\f$ is given by
\f[
\widehat{F}(x) = [1 - F_n(u)]G_{\xi,\beta,u}(x) + F_n(u).
\f]
It can be shown that \f$\widehat{F}(x)\f$ is a generalized
Pareto distribution \f$G_{\xi,\bar{\beta},\bar{u}}(x)\f$ with \f$\bar{\beta}=\beta[1-F_n(u)]^{\xi}\f$
and \f$\bar{u}=u-\bar{\beta}\left\{[1-F_n(u)]^{-\xi}-1\right\}/\xi\f$. By inverting \f$\widehat{F}(x)\f$,
one obtains an estimator for the \f$\alpha\f$-quantile,
\f[
\hat{q}_{\alpha} = \bar{u} + \frac{\bar{\beta}}{\xi}\left[(1-\alpha)^{-\xi}-1\right],
\f]
and similarly an estimator for the (coherent) tail mean,
\f[
\widehat{CTM}_{\alpha} = \hat{q}_{\alpha} - \frac{\bar{\beta}}{\xi-1}(1-\alpha)^{-\xi},
\f]
cf. McNeil and Frey (2000).
Note that in case extreme values of the left tail are fitted, the distribution is mirrored with respect to the
\f$y\f$ axis such that the left tail can be treated as a right tail. The computed fit parameters thus define
the Pareto distribution that fits the mirrored left tail. When quantities like a quantile or a tail mean are
computed using the fit parameters obtained from the mirrored data, the result is mirrored back, yielding the
correct result.
For further details, see
J. R. M. Hosking and J. R. Wallis, Parameter and quantile estimation for the generalized Pareto distribution,
Technometrics, Volume 29, 1987, p. 339-349
A. J. McNeil and R. Frey, Estimation of Tail-Related Risk Measures for Heteroscedastic Financial Time Series:
an Extreme Value Approach, Journal of Empirical Finance, Volume 7, 2000, p. 271-300
@param quantile_probability
@param pot_threshold_value
*/
template<typename Sample, typename LeftRight>
struct peaks_over_threshold_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
// for boost::result_of
typedef boost::tuple<float_type, float_type, float_type> result_type;
// for left tail fitting, mirror the extreme values
typedef mpl::int_<is_same<LeftRight, left>::value ? -1 : 1> sign;
template<typename Args>
peaks_over_threshold_impl(Args const &args)
: Nu_(0)
, mu_(sign::value * numeric::fdiv(args[sample | Sample()], (std::size_t)1))
, sigma2_(numeric::fdiv(args[sample | Sample()], (std::size_t)1))
, threshold_(sign::value * args[pot_threshold_value])
, fit_parameters_(boost::make_tuple(0., 0., 0.))
, is_dirty_(true)
{
}
template<typename Args>
void operator ()(Args const &args)
{
this->is_dirty_ = true;
if (sign::value * args[sample] > this->threshold_)
{
this->mu_ += args[sample];
this->sigma2_ += args[sample] * args[sample];
++this->Nu_;
}
}
template<typename Args>
result_type result(Args const &args) const
{
if (this->is_dirty_)
{
this->is_dirty_ = false;
std::size_t cnt = count(args);
this->mu_ = sign::value * numeric::fdiv(this->mu_, this->Nu_);
this->sigma2_ = numeric::fdiv(this->sigma2_, this->Nu_);
this->sigma2_ -= this->mu_ * this->mu_;
float_type threshold_probability = numeric::fdiv(cnt - this->Nu_, cnt);
float_type tmp = numeric::fdiv(( this->mu_ - this->threshold_ )*( this->mu_ - this->threshold_ ), this->sigma2_);
float_type xi_hat = 0.5 * ( 1. - tmp );
float_type beta_hat = 0.5 * ( this->mu_ - this->threshold_ ) * ( 1. + tmp );
float_type beta_bar = beta_hat * std::pow(1. - threshold_probability, xi_hat);
float_type u_bar = this->threshold_ - beta_bar * ( std::pow(1. - threshold_probability, -xi_hat) - 1.)/xi_hat;
this->fit_parameters_ = boost::make_tuple(u_bar, beta_bar, xi_hat);
}
return this->fit_parameters_;
}
// make this accumulator serializeable
// TODO: do we need to split to load/save and verify that threshold did not change?
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & Nu_;
ar & mu_;
ar & sigma2_;
ar & threshold_;
ar & get<0>(fit_parameters_);
ar & get<1>(fit_parameters_);
ar & get<2>(fit_parameters_);
ar & is_dirty_;
}
private:
std::size_t Nu_; // number of samples larger than threshold
mutable float_type mu_; // mean of Nu_ largest samples
mutable float_type sigma2_; // variance of Nu_ largest samples
float_type threshold_;
mutable result_type fit_parameters_; // boost::tuple that stores fit parameters
mutable bool is_dirty_;
};
///////////////////////////////////////////////////////////////////////////////
// peaks_over_threshold_prob_impl
// determines threshold from a given threshold probability using order statistics
/**
@brief Peaks over Threshold Method for Quantile and Tail Mean Estimation
@sa peaks_over_threshold_impl
@param quantile_probability
@param pot_threshold_probability
*/
template<typename Sample, typename LeftRight>
struct peaks_over_threshold_prob_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
// for boost::result_of
typedef boost::tuple<float_type, float_type, float_type> result_type;
// for left tail fitting, mirror the extreme values
typedef mpl::int_<is_same<LeftRight, left>::value ? -1 : 1> sign;
template<typename Args>
peaks_over_threshold_prob_impl(Args const &args)
: mu_(sign::value * numeric::fdiv(args[sample | Sample()], (std::size_t)1))
, sigma2_(numeric::fdiv(args[sample | Sample()], (std::size_t)1))
, threshold_probability_(args[pot_threshold_probability])
, fit_parameters_(boost::make_tuple(0., 0., 0.))
, is_dirty_(true)
{
}
void operator ()(dont_care)
{
this->is_dirty_ = true;
}
template<typename Args>
result_type result(Args const &args) const
{
if (this->is_dirty_)
{
this->is_dirty_ = false;
std::size_t cnt = count(args);
// the n'th cached sample provides an approximate threshold value u
std::size_t n = static_cast<std::size_t>(
std::ceil(
cnt * ( ( is_same<LeftRight, left>::value ) ? this->threshold_probability_ : 1. - this->threshold_probability_ )
)
);
// If n is in a valid range, return result, otherwise return NaN or throw exception
if ( n >= static_cast<std::size_t>(tail(args).size()))
{
if (std::numeric_limits<float_type>::has_quiet_NaN)
{
return boost::make_tuple(
std::numeric_limits<float_type>::quiet_NaN()
, std::numeric_limits<float_type>::quiet_NaN()
, std::numeric_limits<float_type>::quiet_NaN()
);
}
else
{
std::ostringstream msg;
msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
boost::throw_exception(std::runtime_error(msg.str()));
return boost::make_tuple(Sample(0), Sample(0), Sample(0));
}
}
else
{
float_type u = *(tail(args).begin() + n - 1) * sign::value;
// compute mean and variance of samples above/under threshold value u
for (std::size_t i = 0; i < n; ++i)
{
mu_ += *(tail(args).begin() + i);
sigma2_ += *(tail(args).begin() + i) * (*(tail(args).begin() + i));
}
this->mu_ = sign::value * numeric::fdiv(this->mu_, n);
this->sigma2_ = numeric::fdiv(this->sigma2_, n);
this->sigma2_ -= this->mu_ * this->mu_;
if (is_same<LeftRight, left>::value)
this->threshold_probability_ = 1. - this->threshold_probability_;
float_type tmp = numeric::fdiv(( this->mu_ - u )*( this->mu_ - u ), this->sigma2_);
float_type xi_hat = 0.5 * ( 1. - tmp );
float_type beta_hat = 0.5 * ( this->mu_ - u ) * ( 1. + tmp );
float_type beta_bar = beta_hat * std::pow(1. - threshold_probability_, xi_hat);
float_type u_bar = u - beta_bar * ( std::pow(1. - threshold_probability_, -xi_hat) - 1.)/xi_hat;
this->fit_parameters_ = boost::make_tuple(u_bar, beta_bar, xi_hat);
}
}
return this->fit_parameters_;
}
// make this accumulator serializeable
// TODO: do we need to split to load/save and verify that threshold did not change?
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & mu_;
ar & sigma2_;
ar & threshold_probability_;
ar & get<0>(fit_parameters_);
ar & get<1>(fit_parameters_);
ar & get<2>(fit_parameters_);
ar & is_dirty_;
}
private:
mutable float_type mu_; // mean of samples above threshold u
mutable float_type sigma2_; // variance of samples above threshold u
mutable float_type threshold_probability_;
mutable result_type fit_parameters_; // boost::tuple that stores fit parameters
mutable bool is_dirty_;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::peaks_over_threshold
//
namespace tag
{
template<typename LeftRight>
struct peaks_over_threshold
: depends_on<count>
, pot_threshold_value
{
/// INTERNAL ONLY
///
typedef accumulators::impl::peaks_over_threshold_impl<mpl::_1, LeftRight> impl;
};
template<typename LeftRight>
struct peaks_over_threshold_prob
: depends_on<count, tail<LeftRight> >
, pot_threshold_probability
{
/// INTERNAL ONLY
///
typedef accumulators::impl::peaks_over_threshold_prob_impl<mpl::_1, LeftRight> impl;
};
struct abstract_peaks_over_threshold
: depends_on<>
{
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::peaks_over_threshold
//
namespace extract
{
extractor<tag::abstract_peaks_over_threshold> const peaks_over_threshold = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(peaks_over_threshold)
}
using extract::peaks_over_threshold;
// peaks_over_threshold<LeftRight>(with_threshold_value) -> peaks_over_threshold<LeftRight>
template<typename LeftRight>
struct as_feature<tag::peaks_over_threshold<LeftRight>(with_threshold_value)>
{
typedef tag::peaks_over_threshold<LeftRight> type;
};
// peaks_over_threshold<LeftRight>(with_threshold_probability) -> peaks_over_threshold_prob<LeftRight>
template<typename LeftRight>
struct as_feature<tag::peaks_over_threshold<LeftRight>(with_threshold_probability)>
{
typedef tag::peaks_over_threshold_prob<LeftRight> type;
};
template<typename LeftRight>
struct feature_of<tag::peaks_over_threshold<LeftRight> >
: feature_of<tag::abstract_peaks_over_threshold>
{
};
template<typename LeftRight>
struct feature_of<tag::peaks_over_threshold_prob<LeftRight> >
: feature_of<tag::abstract_peaks_over_threshold>
{
};
// So that peaks_over_threshold can be automatically substituted
// with weighted_peaks_over_threshold when the weight parameter is non-void.
template<typename LeftRight>
struct as_weighted_feature<tag::peaks_over_threshold<LeftRight> >
{
typedef tag::weighted_peaks_over_threshold<LeftRight> type;
};
template<typename LeftRight>
struct feature_of<tag::weighted_peaks_over_threshold<LeftRight> >
: feature_of<tag::peaks_over_threshold<LeftRight> >
{};
// So that peaks_over_threshold_prob can be automatically substituted
// with weighted_peaks_over_threshold_prob when the weight parameter is non-void.
template<typename LeftRight>
struct as_weighted_feature<tag::peaks_over_threshold_prob<LeftRight> >
{
typedef tag::weighted_peaks_over_threshold_prob<LeftRight> type;
};
template<typename LeftRight>
struct feature_of<tag::weighted_peaks_over_threshold_prob<LeftRight> >
: feature_of<tag::peaks_over_threshold_prob<LeftRight> >
{};
}} // namespace boost::accumulators
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,212 @@
///////////////////////////////////////////////////////////////////////////////
// pot_quantile.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_POT_QUANTILE_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_POT_QUANTILE_HPP_DE_01_01_2006
#include <vector>
#include <limits>
#include <numeric>
#include <functional>
#include <boost/parameter/keyword.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/tail.hpp>
#include <boost/accumulators/statistics/peaks_over_threshold.hpp>
#include <boost/accumulators/statistics/weighted_peaks_over_threshold.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// pot_quantile_impl
//
/**
@brief Quantile Estimation based on Peaks over Threshold Method (for both left and right tails)
Computes an estimate
\f[
\hat{q}_{\alpha} = \bar{u} + \frac{\bar{\beta}}{\xi}\left[(1-\alpha)^{-\xi}-1\right]
\f]
for a right or left extreme quantile, \f$\bar[u]\f$, \f$\bar{\beta}\f$ and \f$\xi\f$ being the parameters of the
generalized Pareto distribution that approximates the right tail of the distribution (or the mirrored left tail,
in case the left tail is used). In the latter case, the result is mirrored back, yielding the correct result.
*/
template<typename Sample, typename Impl, typename LeftRight>
struct pot_quantile_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
// for boost::result_of
typedef float_type result_type;
pot_quantile_impl(dont_care)
: sign_((is_same<LeftRight, left>::value) ? -1 : 1)
{
}
template<typename Args>
result_type result(Args const &args) const
{
typedef
typename mpl::if_<
is_same<Impl, weighted>
, tag::weighted_peaks_over_threshold<LeftRight>
, tag::peaks_over_threshold<LeftRight>
>::type
peaks_over_threshold_tag;
extractor<peaks_over_threshold_tag> const some_peaks_over_threshold = {};
float_type u_bar = some_peaks_over_threshold(args).template get<0>();
float_type beta_bar = some_peaks_over_threshold(args).template get<1>();
float_type xi_hat = some_peaks_over_threshold(args).template get<2>();
return this->sign_ * (u_bar + beta_bar/xi_hat * ( std::pow(
is_same<LeftRight, left>::value ? args[quantile_probability] : 1. - args[quantile_probability]
, -xi_hat
) - 1.));
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & sign_;
}
private:
short sign_; // if the fit parameters from the mirrored left tail extreme values are used, mirror back the result
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::pot_quantile<>
// tag::pot_quantile_prob<>
// tag::weighted_pot_quantile<>
// tag::weighted_pot_quantile_prob<>
//
namespace tag
{
template<typename LeftRight>
struct pot_quantile
: depends_on<peaks_over_threshold<LeftRight> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::pot_quantile_impl<mpl::_1, unweighted, LeftRight> impl;
};
template<typename LeftRight>
struct pot_quantile_prob
: depends_on<peaks_over_threshold_prob<LeftRight> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::pot_quantile_impl<mpl::_1, unweighted, LeftRight> impl;
};
template<typename LeftRight>
struct weighted_pot_quantile
: depends_on<weighted_peaks_over_threshold<LeftRight> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::pot_quantile_impl<mpl::_1, weighted, LeftRight> impl;
};
template<typename LeftRight>
struct weighted_pot_quantile_prob
: depends_on<weighted_peaks_over_threshold_prob<LeftRight> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::pot_quantile_impl<mpl::_1, weighted, LeftRight> impl;
};
}
// pot_quantile<LeftRight>(with_threshold_value) -> pot_quantile<LeftRight>
template<typename LeftRight>
struct as_feature<tag::pot_quantile<LeftRight>(with_threshold_value)>
{
typedef tag::pot_quantile<LeftRight> type;
};
// pot_quantile<LeftRight>(with_threshold_probability) -> pot_quantile_prob<LeftRight>
template<typename LeftRight>
struct as_feature<tag::pot_quantile<LeftRight>(with_threshold_probability)>
{
typedef tag::pot_quantile_prob<LeftRight> type;
};
// weighted_pot_quantile<LeftRight>(with_threshold_value) -> weighted_pot_quantile<LeftRight>
template<typename LeftRight>
struct as_feature<tag::weighted_pot_quantile<LeftRight>(with_threshold_value)>
{
typedef tag::weighted_pot_quantile<LeftRight> type;
};
// weighted_pot_quantile<LeftRight>(with_threshold_probability) -> weighted_pot_quantile_prob<LeftRight>
template<typename LeftRight>
struct as_feature<tag::weighted_pot_quantile<LeftRight>(with_threshold_probability)>
{
typedef tag::weighted_pot_quantile_prob<LeftRight> type;
};
// for the purposes of feature-based dependency resolution,
// pot_quantile<LeftRight> and pot_quantile_prob<LeftRight> provide
// the same feature as quantile
template<typename LeftRight>
struct feature_of<tag::pot_quantile<LeftRight> >
: feature_of<tag::quantile>
{
};
template<typename LeftRight>
struct feature_of<tag::pot_quantile_prob<LeftRight> >
: feature_of<tag::quantile>
{
};
// So that pot_quantile can be automatically substituted
// with weighted_pot_quantile when the weight parameter is non-void.
template<typename LeftRight>
struct as_weighted_feature<tag::pot_quantile<LeftRight> >
{
typedef tag::weighted_pot_quantile<LeftRight> type;
};
template<typename LeftRight>
struct feature_of<tag::weighted_pot_quantile<LeftRight> >
: feature_of<tag::pot_quantile<LeftRight> >
{
};
// So that pot_quantile_prob can be automatically substituted
// with weighted_pot_quantile_prob when the weight parameter is non-void.
template<typename LeftRight>
struct as_weighted_feature<tag::pot_quantile_prob<LeftRight> >
{
typedef tag::weighted_pot_quantile_prob<LeftRight> type;
};
template<typename LeftRight>
struct feature_of<tag::weighted_pot_quantile_prob<LeftRight> >
: feature_of<tag::pot_quantile_prob<LeftRight> >
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,219 @@
///////////////////////////////////////////////////////////////////////////////
// pot_tail_mean.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_POT_TAIL_MEAN_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_POT_TAIL_MEAN_HPP_DE_01_01_2006
#include <vector>
#include <limits>
#include <numeric>
#include <functional>
#include <boost/range.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/peaks_over_threshold.hpp>
#include <boost/accumulators/statistics/weighted_peaks_over_threshold.hpp>
#include <boost/accumulators/statistics/pot_quantile.hpp>
#include <boost/accumulators/statistics/tail_mean.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// pot_tail_mean_impl
//
/**
@brief Estimation of the (coherent) tail mean based on the peaks over threshold method (for both left and right tails)
Computes an estimate for the (coherent) tail mean
\f[
\widehat{CTM}_{\alpha} = \hat{q}_{\alpha} - \frac{\bar{\beta}}{\xi-1}(1-\alpha)^{-\xi},
\f]
where \f$\bar[u]\f$, \f$\bar{\beta}\f$ and \f$\xi\f$ are the parameters of the
generalized Pareto distribution that approximates the right tail of the distribution (or the
mirrored left tail, in case the left tail is used). In the latter case, the result is mirrored
back, yielding the correct result.
*/
template<typename Sample, typename Impl, typename LeftRight>
struct pot_tail_mean_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
// for boost::result_of
typedef float_type result_type;
pot_tail_mean_impl(dont_care)
: sign_((is_same<LeftRight, left>::value) ? -1 : 1)
{
}
template<typename Args>
result_type result(Args const &args) const
{
typedef
typename mpl::if_<
is_same<Impl, weighted>
, tag::weighted_peaks_over_threshold<LeftRight>
, tag::peaks_over_threshold<LeftRight>
>::type
peaks_over_threshold_tag;
typedef
typename mpl::if_<
is_same<Impl, weighted>
, tag::weighted_pot_quantile<LeftRight>
, tag::pot_quantile<LeftRight>
>::type
pot_quantile_tag;
extractor<peaks_over_threshold_tag> const some_peaks_over_threshold = {};
extractor<pot_quantile_tag> const some_pot_quantile = {};
float_type beta_bar = some_peaks_over_threshold(args).template get<1>();
float_type xi_hat = some_peaks_over_threshold(args).template get<2>();
return some_pot_quantile(args) - this->sign_ * beta_bar/( xi_hat - 1. ) * std::pow(
is_same<LeftRight, left>::value ? args[quantile_probability] : 1. - args[quantile_probability]
, -xi_hat);
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & sign_;
}
private:
short sign_; // if the fit parameters from the mirrored left tail extreme values are used, mirror back the result
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::pot_tail_mean
// tag::pot_tail_mean_prob
//
namespace tag
{
template<typename LeftRight>
struct pot_tail_mean
: depends_on<peaks_over_threshold<LeftRight>, pot_quantile<LeftRight> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::pot_tail_mean_impl<mpl::_1, unweighted, LeftRight> impl;
};
template<typename LeftRight>
struct pot_tail_mean_prob
: depends_on<peaks_over_threshold_prob<LeftRight>, pot_quantile_prob<LeftRight> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::pot_tail_mean_impl<mpl::_1, unweighted, LeftRight> impl;
};
template<typename LeftRight>
struct weighted_pot_tail_mean
: depends_on<weighted_peaks_over_threshold<LeftRight>, weighted_pot_quantile<LeftRight> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::pot_tail_mean_impl<mpl::_1, weighted, LeftRight> impl;
};
template<typename LeftRight>
struct weighted_pot_tail_mean_prob
: depends_on<weighted_peaks_over_threshold_prob<LeftRight>, weighted_pot_quantile_prob<LeftRight> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::pot_tail_mean_impl<mpl::_1, weighted, LeftRight> impl;
};
}
// pot_tail_mean<LeftRight>(with_threshold_value) -> pot_tail_mean<LeftRight>
template<typename LeftRight>
struct as_feature<tag::pot_tail_mean<LeftRight>(with_threshold_value)>
{
typedef tag::pot_tail_mean<LeftRight> type;
};
// pot_tail_mean<LeftRight>(with_threshold_probability) -> pot_tail_mean_prob<LeftRight>
template<typename LeftRight>
struct as_feature<tag::pot_tail_mean<LeftRight>(with_threshold_probability)>
{
typedef tag::pot_tail_mean_prob<LeftRight> type;
};
// weighted_pot_tail_mean<LeftRight>(with_threshold_value) -> weighted_pot_tail_mean<LeftRight>
template<typename LeftRight>
struct as_feature<tag::weighted_pot_tail_mean<LeftRight>(with_threshold_value)>
{
typedef tag::weighted_pot_tail_mean<LeftRight> type;
};
// weighted_pot_tail_mean<LeftRight>(with_threshold_probability) -> weighted_pot_tail_mean_prob<LeftRight>
template<typename LeftRight>
struct as_feature<tag::weighted_pot_tail_mean<LeftRight>(with_threshold_probability)>
{
typedef tag::weighted_pot_tail_mean_prob<LeftRight> type;
};
// for the purposes of feature-based dependency resolution,
// pot_tail_mean<LeftRight> and pot_tail_mean_prob<LeftRight> provide
// the same feature as tail_mean
template<typename LeftRight>
struct feature_of<tag::pot_tail_mean<LeftRight> >
: feature_of<tag::tail_mean>
{
};
template<typename LeftRight>
struct feature_of<tag::pot_tail_mean_prob<LeftRight> >
: feature_of<tag::tail_mean>
{
};
// So that pot_tail_mean can be automatically substituted
// with weighted_pot_tail_mean when the weight parameter is non-void.
template<typename LeftRight>
struct as_weighted_feature<tag::pot_tail_mean<LeftRight> >
{
typedef tag::weighted_pot_tail_mean<LeftRight> type;
};
template<typename LeftRight>
struct feature_of<tag::weighted_pot_tail_mean<LeftRight> >
: feature_of<tag::pot_tail_mean<LeftRight> >
{
};
// So that pot_tail_mean_prob can be automatically substituted
// with weighted_pot_tail_mean_prob when the weight parameter is non-void.
template<typename LeftRight>
struct as_weighted_feature<tag::pot_tail_mean_prob<LeftRight> >
{
typedef tag::weighted_pot_tail_mean_prob<LeftRight> type;
};
template<typename LeftRight>
struct feature_of<tag::weighted_pot_tail_mean_prob<LeftRight> >
: feature_of<tag::pot_tail_mean_prob<LeftRight> >
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,84 @@
///////////////////////////////////////////////////////////////////////////////
// rolling_count.hpp
//
// Copyright 2008 Eric Niebler. 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_ACCUMULATORS_STATISTICS_ROLLING_COUNT_HPP_EAN_26_12_2008
#define BOOST_ACCUMULATORS_STATISTICS_ROLLING_COUNT_HPP_EAN_26_12_2008
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/rolling_window.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// rolling_count_impl
// returns the count of elements in the rolling window
template<typename Sample>
struct rolling_count_impl
: accumulator_base
{
typedef std::size_t result_type;
rolling_count_impl(dont_care)
{}
template<typename Args>
result_type result(Args const &args) const
{
return static_cast<std::size_t>(rolling_window_plus1(args).size()) - is_rolling_window_plus1_full(args);
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::rolling_count
//
namespace tag
{
struct rolling_count
: depends_on< rolling_window_plus1 >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::rolling_count_impl< mpl::_1 > impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::rolling_window::window_size named parameter
static boost::parameter::keyword<tag::rolling_window_size> const window_size;
#endif
};
} // namespace tag
///////////////////////////////////////////////////////////////////////////////
// extract::rolling_count
//
namespace extract
{
extractor<tag::rolling_count> const rolling_count = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_count)
}
using extract::rolling_count;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,196 @@
///////////////////////////////////////////////////////////////////////////////
// rolling_mean.hpp
// Copyright (C) 2008 Eric Niebler.
// Copyright (C) 2012 Pieter Bastiaan Ober (Integricom).
// 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_ACCUMULATORS_STATISTICS_ROLLING_MEAN_HPP_EAN_26_12_2008
#define BOOST_ACCUMULATORS_STATISTICS_ROLLING_MEAN_HPP_EAN_26_12_2008
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/rolling_sum.hpp>
#include <boost/accumulators/statistics/rolling_count.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// lazy_rolling_mean_impl
// returns the mean over the rolling window and is calculated only
// when the result is requested
template<typename Sample>
struct lazy_rolling_mean_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t, void, void>::result_type result_type;
lazy_rolling_mean_impl(dont_care)
{
}
template<typename Args>
result_type result(Args const &args) const
{
return numeric::fdiv(rolling_sum(args), rolling_count(args));
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {}
};
///////////////////////////////////////////////////////////////////////////////
// immediate_rolling_mean_impl
// The non-lazy version computes the rolling mean recursively when a new
// sample is added
template<typename Sample>
struct immediate_rolling_mean_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
template<typename Args>
immediate_rolling_mean_impl(Args const &args)
: mean_(numeric::fdiv(args[sample | Sample()],numeric::one<std::size_t>::value))
{
}
template<typename Args>
void operator()(Args const &args)
{
if(is_rolling_window_plus1_full(args))
{
if (rolling_window_plus1(args).front() > args[sample])
mean_ -= numeric::fdiv(rolling_window_plus1(args).front()-args[sample],rolling_count(args));
else if (rolling_window_plus1(args).front() < args[sample])
mean_ += numeric::fdiv(args[sample]-rolling_window_plus1(args).front(),rolling_count(args));
}
else
{
result_type prev_mean = mean_;
if (prev_mean > args[sample])
mean_ -= numeric::fdiv(prev_mean-args[sample],rolling_count(args));
else if (prev_mean < args[sample])
mean_ += numeric::fdiv(args[sample]-prev_mean,rolling_count(args));
}
}
template<typename Args>
result_type result(Args const &) const
{
return mean_;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & mean_;
}
private:
result_type mean_;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::lazy_rolling_mean
// tag::immediate_rolling_mean
// tag::rolling_mean
//
namespace tag
{
struct lazy_rolling_mean
: depends_on< rolling_sum, rolling_count >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::lazy_rolling_mean_impl< mpl::_1 > impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::rolling_window::window_size named parameter
static boost::parameter::keyword<tag::rolling_window_size> const window_size;
#endif
};
struct immediate_rolling_mean
: depends_on< rolling_window_plus1, rolling_count>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::immediate_rolling_mean_impl< mpl::_1> impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::rolling_window::window_size named parameter
static boost::parameter::keyword<tag::rolling_window_size> const window_size;
#endif
};
// make immediate_rolling_mean the default implementation
struct rolling_mean : immediate_rolling_mean {};
} // namespace tag
///////////////////////////////////////////////////////////////////////////////
// extract::lazy_rolling_mean
// extract::immediate_rolling_mean
// extract::rolling_mean
//
namespace extract
{
extractor<tag::lazy_rolling_mean> const lazy_rolling_mean = {};
extractor<tag::immediate_rolling_mean> const immediate_rolling_mean = {};
extractor<tag::rolling_mean> const rolling_mean = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(lazy_rolling_mean)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(immediate_rolling_mean)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_mean)
}
using extract::lazy_rolling_mean;
using extract::immediate_rolling_mean;
using extract::rolling_mean;
// rolling_mean(lazy) -> lazy_rolling_mean
template<>
struct as_feature<tag::rolling_mean(lazy)>
{
typedef tag::lazy_rolling_mean type;
};
// rolling_mean(immediate) -> immediate_rolling_mean
template<>
struct as_feature<tag::rolling_mean(immediate)>
{
typedef tag::immediate_rolling_mean type;
};
// for the purposes of feature-based dependency resolution,
// immediate_rolling_mean provides the same feature as rolling_mean
template<>
struct feature_of<tag::immediate_rolling_mean>
: feature_of<tag::rolling_mean>
{
};
// for the purposes of feature-based dependency resolution,
// lazy_rolling_mean provides the same feature as rolling_mean
template<>
struct feature_of<tag::lazy_rolling_mean>
: feature_of<tag::rolling_mean>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,120 @@
///////////////////////////////////////////////////////////////////////////////
// rolling_moment.hpp
// Copyright 2005 Eric Niebler.
// Copyright (C) 2014 Pieter Bastiaan Ober (Integricom).
// 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_ACCUMULATORS_STATISTICS_ROLLING_MOMENT_HPP_EAN_27_11_2005
#define BOOST_ACCUMULATORS_STATISTICS_ROLLING_MOMENT_HPP_EAN_27_11_2005
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/rolling_count.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// rolling_moment_impl
template<typename N, typename Sample>
struct rolling_moment_impl
: accumulator_base
{
BOOST_MPL_ASSERT_RELATION(N::value, >, 0);
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t,void,void>::result_type result_type;
template<typename Args>
rolling_moment_impl(Args const &args)
: sum_(args[sample | Sample()])
{
}
template<typename Args>
void operator ()(Args const &args)
{
if(is_rolling_window_plus1_full(args))
{
this->sum_ -= numeric::pow(rolling_window_plus1(args).front(), N());
}
this->sum_ += numeric::pow(args[sample], N());
}
template<typename Args>
result_type result(Args const &args) const
{
return numeric::fdiv(this->sum_, rolling_count(args));
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & sum_;
}
private:
result_type sum_;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::rolling_moment
//
namespace tag
{
template<int N>
struct rolling_moment
: depends_on< rolling_window_plus1, rolling_count>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::rolling_moment_impl<mpl::int_<N>, mpl::_1> impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::rolling_window::window_size named parameter
static boost::parameter::keyword<tag::rolling_window_size> const window_size;
#endif
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::rolling_moment
//
namespace extract
{
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, rolling_moment, (int))
}
using extract::rolling_moment;
// There is no weighted_rolling_moment (yet)...
//
//// So that rolling_moment<N> can be automatically substituted with
//// weighted_rolling_moment<N> when the weight parameter is non-void
//template<int N>
//struct as_weighted_feature<tag::rolling_moment<N> >
//{
// typedef tag::weighted_rolling_moment<N> type;
//};
//
//template<int N>
//struct feature_of<tag::weighted_rolling_moment<N> >
// : feature_of<tag::rolling_moment<N> >
//{
//};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,98 @@
///////////////////////////////////////////////////////////////////////////////
// rolling_sum.hpp
//
// Copyright 2008 Eric Niebler. 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_ACCUMULATORS_STATISTICS_ROLLING_SUM_HPP_EAN_26_12_2008
#define BOOST_ACCUMULATORS_STATISTICS_ROLLING_SUM_HPP_EAN_26_12_2008
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/rolling_window.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// rolling_sum_impl
// returns the sum of the samples in the rolling window
template<typename Sample>
struct rolling_sum_impl
: accumulator_base
{
typedef Sample result_type;
template<typename Args>
rolling_sum_impl(Args const &args)
: sum_(args[sample | Sample()])
{}
template<typename Args>
void operator ()(Args const &args)
{
if(is_rolling_window_plus1_full(args))
{
this->sum_ -= rolling_window_plus1(args).front();
}
this->sum_ += args[sample];
}
template<typename Args>
result_type result(Args const & /*args*/) const
{
return this->sum_;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & sum_;
}
private:
Sample sum_;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::rolling_sum
//
namespace tag
{
struct rolling_sum
: depends_on< rolling_window_plus1 >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::rolling_sum_impl< mpl::_1 > impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::rolling_window::window_size named parameter
static boost::parameter::keyword<tag::rolling_window_size> const window_size;
#endif
};
} // namespace tag
///////////////////////////////////////////////////////////////////////////////
// extract::rolling_sum
//
namespace extract
{
extractor<tag::rolling_sum> const rolling_sum = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_sum)
}
using extract::rolling_sum;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,259 @@
///////////////////////////////////////////////////////////////////////////////
// rolling_variance.hpp
// Copyright (C) 2005 Eric Niebler
// Copyright (C) 2014 Pieter Bastiaan Ober (Integricom).
// 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_ACCUMULATORS_STATISTICS_ROLLING_VARIANCE_HPP_EAN_15_11_2011
#define BOOST_ACCUMULATORS_STATISTICS_ROLLING_VARIANCE_HPP_EAN_15_11_2011
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/rolling_mean.hpp>
#include <boost/accumulators/statistics/rolling_moment.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/utility/enable_if.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
//! Immediate (lazy) calculation of the rolling variance.
/*!
Calculation of sample variance \f$\sigma_n^2\f$ is done as follows, see also
http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance.
For a rolling window of size \f$N\f$, when \f$n <= N\f$, the variance is computed according to the formula
\f[
\sigma_n^2 = \frac{1}{n-1} \sum_{i = 1}^n (x_i - \mu_n)^2.
\f]
When \f$n > N\f$, the sample variance over the window becomes:
\f[
\sigma_n^2 = \frac{1}{N-1} \sum_{i = n-N+1}^n (x_i - \mu_n)^2.
\f]
*/
///////////////////////////////////////////////////////////////////////////////
// lazy_rolling_variance_impl
//
template<typename Sample>
struct lazy_rolling_variance_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t,void,void>::result_type result_type;
lazy_rolling_variance_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
result_type mean = rolling_mean(args);
size_t nr_samples = rolling_count(args);
if (nr_samples < 2) return result_type();
return nr_samples*(rolling_moment<2>(args) - mean*mean)/(nr_samples-1);
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {}
};
//! Iterative calculation of the rolling variance.
/*!
Iterative calculation of sample variance \f$\sigma_n^2\f$ is done as follows, see also
http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance.
For a rolling window of size \f$N\f$, for the first \f$N\f$ samples, the variance is computed according to the formula
\f[
\sigma_n^2 = \frac{1}{n-1} \sum_{i = 1}^n (x_i - \mu_n)^2 = \frac{1}{n-1}M_{2,n},
\f]
where the sum of squares \f$M_{2,n}\f$ can be recursively computed as:
\f[
M_{2,n} = \sum_{i = 1}^n (x_i - \mu_n)^2 = M_{2,n-1} + (x_n - \mu_n)(x_n - \mu_{n-1}),
\f]
and the estimate of the sample mean as:
\f[
\mu_n = \frac{1}{n} \sum_{i = 1}^n x_i = \mu_{n-1} + \frac{1}{n}(x_n - \mu_{n-1}).
\f]
For further samples, when the rolling window is fully filled with data, one has to take into account that the oldest
sample \f$x_{n-N}\f$ is dropped from the window. The sample variance over the window now becomes:
\f[
\sigma_n^2 = \frac{1}{N-1} \sum_{i = n-N+1}^n (x_i - \mu_n)^2 = \frac{1}{n-1}M_{2,n},
\f]
where the sum of squares \f$M_{2,n}\f$ now equals:
\f[
M_{2,n} = \sum_{i = n-N+1}^n (x_i - \mu_n)^2 = M_{2,n-1} + (x_n - \mu_n)(x_n - \mu_{n-1}) - (x_{n-N} - \mu_n)(x_{n-N} - \mu_{n-1}),
\f]
and the estimated mean is:
\f[
\mu_n = \frac{1}{N} \sum_{i = n-N+1}^n x_i = \mu_{n-1} + \frac{1}{n}(x_n - x_{n-N}).
\f]
Note that the sample variance is not defined for \f$n <= 1\f$.
*/
///////////////////////////////////////////////////////////////////////////////
// immediate_rolling_variance_impl
//
template<typename Sample>
struct immediate_rolling_variance_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
template<typename Args>
immediate_rolling_variance_impl(Args const &args)
: previous_mean_(numeric::fdiv(args[sample | Sample()], numeric::one<std::size_t>::value))
, sum_of_squares_(numeric::fdiv(args[sample | Sample()], numeric::one<std::size_t>::value))
{
}
template<typename Args>
void operator()(Args const &args)
{
Sample added_sample = args[sample];
result_type mean = immediate_rolling_mean(args);
sum_of_squares_ += (added_sample-mean)*(added_sample-previous_mean_);
if(is_rolling_window_plus1_full(args))
{
Sample removed_sample = rolling_window_plus1(args).front();
sum_of_squares_ -= (removed_sample-mean)*(removed_sample-previous_mean_);
prevent_underflow(sum_of_squares_);
}
previous_mean_ = mean;
}
template<typename Args>
result_type result(Args const &args) const
{
size_t nr_samples = rolling_count(args);
if (nr_samples < 2) return result_type();
return numeric::fdiv(sum_of_squares_,(nr_samples-1));
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & previous_mean_;
ar & sum_of_squares_;
}
private:
result_type previous_mean_;
result_type sum_of_squares_;
template<typename T>
void prevent_underflow(T &non_negative_number,typename boost::enable_if<boost::is_arithmetic<T>,T>::type* = 0)
{
if (non_negative_number < T(0)) non_negative_number = T(0);
}
template<typename T>
void prevent_underflow(T &non_arithmetic_quantity,typename boost::disable_if<boost::is_arithmetic<T>,T>::type* = 0)
{
}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag:: lazy_rolling_variance
// tag:: immediate_rolling_variance
// tag:: rolling_variance
//
namespace tag
{
struct lazy_rolling_variance
: depends_on< rolling_count, rolling_mean, rolling_moment<2> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::lazy_rolling_variance_impl< mpl::_1 > impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::rolling_window::window_size named parameter
static boost::parameter::keyword<tag::rolling_window_size> const window_size;
#endif
};
struct immediate_rolling_variance
: depends_on< rolling_window_plus1, rolling_count, immediate_rolling_mean>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::immediate_rolling_variance_impl< mpl::_1> impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::rolling_window::window_size named parameter
static boost::parameter::keyword<tag::rolling_window_size> const window_size;
#endif
};
// make immediate_rolling_variance the default implementation
struct rolling_variance : immediate_rolling_variance {};
} // namespace tag
///////////////////////////////////////////////////////////////////////////////
// extract::lazy_rolling_variance
// extract::immediate_rolling_variance
// extract::rolling_variance
//
namespace extract
{
extractor<tag::lazy_rolling_variance> const lazy_rolling_variance = {};
extractor<tag::immediate_rolling_variance> const immediate_rolling_variance = {};
extractor<tag::rolling_variance> const rolling_variance = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(lazy_rolling_variance)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(immediate_rolling_variance)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_variance)
}
using extract::lazy_rolling_variance;
using extract::immediate_rolling_variance;
using extract::rolling_variance;
// rolling_variance(lazy) -> lazy_rolling_variance
template<>
struct as_feature<tag::rolling_variance(lazy)>
{
typedef tag::lazy_rolling_variance type;
};
// rolling_variance(immediate) -> immediate_rolling_variance
template<>
struct as_feature<tag::rolling_variance(immediate)>
{
typedef tag::immediate_rolling_variance type;
};
// for the purposes of feature-based dependency resolution,
// lazy_rolling_variance provides the same feature as rolling_variance
template<>
struct feature_of<tag::lazy_rolling_variance>
: feature_of<tag::rolling_variance>
{
};
// for the purposes of feature-based dependency resolution,
// immediate_rolling_variance provides the same feature as rolling_variance
template<>
struct feature_of<tag::immediate_rolling_variance>
: feature_of<tag::rolling_variance>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,221 @@
///////////////////////////////////////////////////////////////////////////////
// rolling_window.hpp
//
// Copyright 2008 Eric Niebler. 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_ACCUMULATORS_STATISTICS_ROLLING_WINDOW_HPP_EAN_26_12_2008
#define BOOST_ACCUMULATORS_STATISTICS_ROLLING_WINDOW_HPP_EAN_26_12_2008
#include <cstddef>
#include <boost/version.hpp>
#include <boost/assert.hpp>
#include <boost/circular_buffer.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/parameters/accumulator.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/serialization/split_free.hpp>
namespace boost { namespace serialization {
// implement serialization for boost::circular_buffer
template <class Archive, class T>
void save(Archive& ar, const circular_buffer<T>& b, const unsigned int /* version */)
{
typename circular_buffer<T>::size_type size = b.size();
ar << b.capacity();
ar << size;
const typename circular_buffer<T>::const_array_range one = b.array_one();
const typename circular_buffer<T>::const_array_range two = b.array_two();
ar.save_binary(one.first, one.second*sizeof(T));
ar.save_binary(two.first, two.second*sizeof(T));
}
template <class Archive, class T>
void load(Archive& ar, circular_buffer<T>& b, const unsigned int /* version */)
{
typename circular_buffer<T>::capacity_type capacity;
typename circular_buffer<T>::size_type size;
ar >> capacity;
b.set_capacity(capacity);
ar >> size;
b.clear();
const typename circular_buffer<T>::pointer buff = new T[size*sizeof(T)];
ar.load_binary(buff, size*sizeof(T));
b.insert(b.begin(), buff, buff+size);
delete[] buff;
}
template<class Archive, class T>
inline void serialize(Archive & ar, circular_buffer<T>& b, const unsigned int version)
{
split_free(ar, b, version);
}
} } // end namespace boost::serialization
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////////
// tag::rolling_window::size named parameter
BOOST_PARAMETER_NESTED_KEYWORD(tag, rolling_window_size, window_size)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window_size)
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// rolling_window_plus1_impl
// stores the latest N+1 samples, where N is specified at construction time
// with the rolling_window_size named parameter
template<typename Sample>
struct rolling_window_plus1_impl
: accumulator_base
{
typedef typename circular_buffer<Sample>::const_iterator const_iterator;
typedef iterator_range<const_iterator> result_type;
template<typename Args>
rolling_window_plus1_impl(Args const & args)
: buffer_(args[rolling_window_size] + 1)
{}
#if BOOST_VERSION < 103600
// Before Boost 1.36, copying a circular buffer didn't copy
// it's capacity, and we need that behavior.
rolling_window_plus1_impl(rolling_window_plus1_impl const &that)
: buffer_(that.buffer_)
{
this->buffer_.set_capacity(that.buffer_.capacity());
}
rolling_window_plus1_impl &operator =(rolling_window_plus1_impl const &that)
{
this->buffer_ = that.buffer_;
this->buffer_.set_capacity(that.buffer_.capacity());
}
#endif
template<typename Args>
void operator ()(Args const &args)
{
this->buffer_.push_back(args[sample]);
}
bool full() const
{
return this->buffer_.full();
}
// The result of a shifted rolling window is the range including
// everything except the most recently added element.
result_type result(dont_care) const
{
return result_type(this->buffer_.begin(), this->buffer_.end());
}
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & buffer_;
}
private:
circular_buffer<Sample> buffer_;
};
template<typename Args>
bool is_rolling_window_plus1_full(Args const &args)
{
return find_accumulator<tag::rolling_window_plus1>(args[accumulator]).full();
}
///////////////////////////////////////////////////////////////////////////////
// rolling_window_impl
// stores the latest N samples, where N is specified at construction type
// with the rolling_window_size named parameter
template<typename Sample>
struct rolling_window_impl
: accumulator_base
{
typedef typename circular_buffer<Sample>::const_iterator const_iterator;
typedef iterator_range<const_iterator> result_type;
rolling_window_impl(dont_care)
{}
template<typename Args>
result_type result(Args const &args) const
{
return rolling_window_plus1(args).advance_begin(is_rolling_window_plus1_full(args));
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::rolling_window_plus1
// tag::rolling_window
//
namespace tag
{
struct rolling_window_plus1
: depends_on<>
, tag::rolling_window_size
{
/// INTERNAL ONLY
///
typedef accumulators::impl::rolling_window_plus1_impl< mpl::_1 > impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::rolling_window::size named parameter
static boost::parameter::keyword<tag::rolling_window_size> const window_size;
#endif
};
struct rolling_window
: depends_on< rolling_window_plus1 >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::rolling_window_impl< mpl::_1 > impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::rolling_window::size named parameter
static boost::parameter::keyword<tag::rolling_window_size> const window_size;
#endif
};
} // namespace tag
///////////////////////////////////////////////////////////////////////////////
// extract::rolling_window_plus1
// extract::rolling_window
//
namespace extract
{
extractor<tag::rolling_window_plus1> const rolling_window_plus1 = {};
extractor<tag::rolling_window> const rolling_window = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window_plus1)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(rolling_window)
}
using extract::rolling_window_plus1;
using extract::rolling_window;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,118 @@
///////////////////////////////////////////////////////////////////////////////
// skewness.hpp
//
// Copyright 2006 Olivier Gygi, Daniel Egloff. 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_ACCUMULATORS_STATISTICS_SKEWNESS_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_SKEWNESS_HPP_EAN_28_10_2005
#include <limits>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/moment.hpp>
#include <boost/accumulators/statistics/mean.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// skewness_impl
/**
@brief Skewness estimation
The skewness of a sample distribution is defined as the ratio of the 3rd central moment and the \f$ 3/2 \f$-th power
of the 2nd central moment (the variance) of the samples 3. The skewness can also be expressed by the simple moments:
\f[
\hat{g}_1 =
\frac
{\widehat{m}_n^{(3)}-3\widehat{m}_n^{(2)}\hat{\mu}_n+2\hat{\mu}_n^3}
{\left(\widehat{m}_n^{(2)} - \hat{\mu}_n^{2}\right)^{3/2}}
\f]
where \f$ \widehat{m}_n^{(i)} \f$ are the \f$ i \f$-th moment and \f$ \hat{\mu}_n \f$ the mean (first moment) of the
\f$ n \f$ samples.
*/
template<typename Sample>
struct skewness_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, Sample>::result_type result_type;
skewness_impl(dont_care)
{
}
template<typename Args>
result_type result(Args const &args) const
{
return numeric::fdiv(
accumulators::moment<3>(args)
- 3. * accumulators::moment<2>(args) * mean(args)
+ 2. * mean(args) * mean(args) * mean(args)
, ( accumulators::moment<2>(args) - mean(args) * mean(args) )
* std::sqrt( accumulators::moment<2>(args) - mean(args) * mean(args) )
);
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::skewness
//
namespace tag
{
struct skewness
: depends_on<mean, moment<2>, moment<3> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::skewness_impl<mpl::_1> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::skewness
//
namespace extract
{
extractor<tag::skewness> const skewness = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(skewness)
}
using extract::skewness;
// So that skewness can be automatically substituted with
// weighted_skewness when the weight parameter is non-void
template<>
struct as_weighted_feature<tag::skewness>
{
typedef tag::weighted_skewness type;
};
template<>
struct feature_of<tag::weighted_skewness>
: feature_of<tag::skewness>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,29 @@
///////////////////////////////////////////////////////////////////////////////
/// \file stats.hpp
/// Contains the stats<> template.
///
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_STATS_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_STATS_HPP_EAN_28_10_2005
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////////
/// An MPL sequence of statistics.
template<BOOST_PP_ENUM_PARAMS(BOOST_ACCUMULATORS_MAX_FEATURES, typename Stat)>
struct stats
: mpl::vector<BOOST_PP_ENUM_PARAMS(BOOST_ACCUMULATORS_MAX_FEATURES, Stat)>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,146 @@
///////////////////////////////////////////////////////////////////////////////
// sum.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_SUM_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_SUM_HPP_EAN_28_10_2005
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/parameters/weight.hpp>
#include <boost/accumulators/framework/accumulators/external_accumulator.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// sum_impl
template<typename Sample, typename Tag>
struct sum_impl
: accumulator_base
{
// for boost::result_of
typedef Sample result_type;
template<typename Args>
sum_impl(Args const &args)
: sum(args[parameter::keyword<Tag>::get() | Sample()])
{
}
template<typename Args>
void operator ()(Args const &args)
{
// what about overflow?
this->sum += args[parameter::keyword<Tag>::get()];
}
result_type result(dont_care) const
{
return this->sum;
}
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */)
{
ar & sum;
}
private:
Sample sum;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::sum
// tag::sum_of_weights
// tag::sum_of_variates
//
namespace tag
{
struct sum
: depends_on<>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::sum_impl<mpl::_1, tag::sample> impl;
};
struct sum_of_weights
: depends_on<>
{
typedef mpl::true_ is_weight_accumulator;
/// INTERNAL ONLY
///
typedef accumulators::impl::sum_impl<mpl::_2, tag::weight> impl;
};
template<typename VariateType, typename VariateTag>
struct sum_of_variates
: depends_on<>
{
/// INTERNAL ONLY
///
typedef mpl::always<accumulators::impl::sum_impl<VariateType, VariateTag> > impl;
};
struct abstract_sum_of_variates
: depends_on<>
{
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::sum
// extract::sum_of_weights
// extract::sum_of_variates
//
namespace extract
{
extractor<tag::sum> const sum = {};
extractor<tag::sum_of_weights> const sum_of_weights = {};
extractor<tag::abstract_sum_of_variates> const sum_of_variates = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(sum)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(sum_of_weights)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(sum_of_variates)
}
using extract::sum;
using extract::sum_of_weights;
using extract::sum_of_variates;
// So that mean can be automatically substituted with
// weighted_mean when the weight parameter is non-void.
template<>
struct as_weighted_feature<tag::sum>
{
typedef tag::weighted_sum type;
};
template<>
struct feature_of<tag::weighted_sum>
: feature_of<tag::sum>
{};
template<typename VariateType, typename VariateTag>
struct feature_of<tag::sum_of_variates<VariateType, VariateTag> >
: feature_of<tag::abstract_sum_of_variates>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,196 @@
///////////////////////////////////////////////////////////////////////////////
// sum_kahan.hpp
//
// Copyright 2010 Gaetano Mendola, 2011 Simon West. 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_ACCUMULATORS_STATISTICS_SUM_KAHAN_HPP_EAN_26_07_2010
#define BOOST_ACCUMULATORS_STATISTICS_SUM_KAHAN_HPP_EAN_26_07_2010
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/weighted_sum_kahan.hpp>
#include <boost/numeric/conversion/cast.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
#if _MSC_VER > 1400
# pragma float_control(push)
# pragma float_control(precise, on)
#endif
template<typename Sample, typename Tag>
struct sum_kahan_impl
: accumulator_base
{
typedef Sample result_type;
////////////////////////////////////////////////////////////////////////////
// sum_kahan_impl
/**
@brief Kahan summation algorithm
The Kahan summation algorithm reduces the numerical error obtained with standard
sequential sum.
*/
template<typename Args>
sum_kahan_impl(Args const & args)
: sum(args[parameter::keyword<Tag>::get() | Sample()]),
compensation(boost::numeric_cast<Sample>(0.0))
{
}
template<typename Args>
void
#if BOOST_ACCUMULATORS_GCC_VERSION > 40305
__attribute__((__optimize__("no-associative-math")))
#endif
operator ()(Args const & args)
{
const Sample myTmp1 = args[parameter::keyword<Tag>::get()] - this->compensation;
const Sample myTmp2 = this->sum + myTmp1;
this->compensation = (myTmp2 - this->sum) - myTmp1;
this->sum = myTmp2;
}
result_type result(dont_care) const
{
return this->sum;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & sum;
ar & compensation;
}
private:
Sample sum;
Sample compensation;
};
#if _MSC_VER > 1400
# pragma float_control(pop)
#endif
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::sum_kahan
// tag::sum_of_weights_kahan
// tag::sum_of_variates_kahan
//
namespace tag
{
struct sum_kahan
: depends_on<>
{
/// INTERNAL ONLY
///
typedef impl::sum_kahan_impl< mpl::_1, tag::sample > impl;
};
struct sum_of_weights_kahan
: depends_on<>
{
typedef mpl::true_ is_weight_accumulator;
/// INTERNAL ONLY
///
typedef accumulators::impl::sum_kahan_impl<mpl::_2, tag::weight> impl;
};
template<typename VariateType, typename VariateTag>
struct sum_of_variates_kahan
: depends_on<>
{
/// INTERNAL ONLY
///
typedef mpl::always<accumulators::impl::sum_kahan_impl<VariateType, VariateTag> > impl;
};
} // namespace tag
///////////////////////////////////////////////////////////////////////////////
// extract::sum_kahan
// extract::sum_of_weights_kahan
// extract::sum_of_variates_kahan
//
namespace extract
{
extractor<tag::sum_kahan> const sum_kahan = {};
extractor<tag::sum_of_weights_kahan> const sum_of_weights_kahan = {};
extractor<tag::abstract_sum_of_variates> const sum_of_variates_kahan = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(sum_kahan)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(sum_of_weights_kahan)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(sum_of_variates_kahan)
} // namespace extract
using extract::sum_kahan;
using extract::sum_of_weights_kahan;
using extract::sum_of_variates_kahan;
// sum(kahan) -> sum_kahan
template<>
struct as_feature<tag::sum(kahan)>
{
typedef tag::sum_kahan type;
};
// sum_of_weights(kahan) -> sum_of_weights_kahan
template<>
struct as_feature<tag::sum_of_weights(kahan)>
{
typedef tag::sum_of_weights_kahan type;
};
// So that sum_kahan can be automatically substituted with
// weighted_sum_kahan when the weight parameter is non-void.
template<>
struct as_weighted_feature<tag::sum_kahan>
{
typedef tag::weighted_sum_kahan type;
};
template<>
struct feature_of<tag::weighted_sum_kahan>
: feature_of<tag::sum>
{};
// for the purposes of feature-based dependency resolution,
// sum_kahan provides the same feature as sum
template<>
struct feature_of<tag::sum_kahan>
: feature_of<tag::sum>
{
};
// for the purposes of feature-based dependency resolution,
// sum_of_weights_kahan provides the same feature as sum_of_weights
template<>
struct feature_of<tag::sum_of_weights_kahan>
: feature_of<tag::sum_of_weights>
{
};
template<typename VariateType, typename VariateTag>
struct feature_of<tag::sum_of_variates_kahan<VariateType, VariateTag> >
: feature_of<tag::abstract_sum_of_variates>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,352 @@
///////////////////////////////////////////////////////////////////////////////
// tail.hpp
//
// Copyright 2005 Eric Niebler, Michael Gauckler. 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_ACCUMULATORS_STATISTICS_TAIL_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_TAIL_HPP_EAN_28_10_2005
#include <vector>
#include <functional>
#include <boost/assert.hpp>
#include <boost/range.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
namespace boost { namespace accumulators
{
///////////////////////////////////////////////////////////////////////////////
// cache_size named parameters
BOOST_PARAMETER_NESTED_KEYWORD(tag, right_tail_cache_size, cache_size)
BOOST_PARAMETER_NESTED_KEYWORD(tag, left_tail_cache_size, cache_size)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(right_tail_cache_size)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(left_tail_cache_size)
namespace detail
{
///////////////////////////////////////////////////////////////////////////////
// tail_range
/// INTERNAL ONLY
///
template<typename ElementIterator, typename IndexIterator>
struct tail_range
{
typedef boost::iterator_range<
boost::reverse_iterator<boost::permutation_iterator<ElementIterator, IndexIterator> >
> type;
};
///////////////////////////////////////////////////////////////////////////////
// make_tail_range
/// INTERNAL ONLY
///
template<typename ElementIterator, typename IndexIterator>
typename tail_range<ElementIterator, IndexIterator>::type
make_tail_range(ElementIterator elem_begin, IndexIterator index_begin, IndexIterator index_end)
{
return boost::make_iterator_range(
boost::make_reverse_iterator(
boost::make_permutation_iterator(elem_begin, index_end)
)
, boost::make_reverse_iterator(
boost::make_permutation_iterator(elem_begin, index_begin)
)
);
}
///////////////////////////////////////////////////////////////////////////////
// stat_assign_visitor
/// INTERNAL ONLY
///
template<typename Args>
struct stat_assign_visitor
{
stat_assign_visitor(Args const &a, std::size_t i)
: args(a)
, index(i)
{
}
template<typename Stat>
void operator ()(Stat &stat) const
{
stat.assign(this->args, this->index);
}
private:
BOOST_DELETED_FUNCTION(stat_assign_visitor &operator =(stat_assign_visitor const &))
Args const &args;
std::size_t index;
};
///////////////////////////////////////////////////////////////////////////////
// stat_assign
/// INTERNAL ONLY
///
template<typename Args>
inline stat_assign_visitor<Args> const stat_assign(Args const &args, std::size_t index)
{
return stat_assign_visitor<Args>(args, index);
}
///////////////////////////////////////////////////////////////////////////////
// is_tail_variate_feature
/// INTERNAL ONLY
///
template<typename Stat, typename LeftRight>
struct is_tail_variate_feature
: mpl::false_
{
};
/// INTERNAL ONLY
///
template<typename VariateType, typename VariateTag, typename LeftRight>
struct is_tail_variate_feature<tag::tail_variate<VariateType, VariateTag, LeftRight>, LeftRight>
: mpl::true_
{
};
/// INTERNAL ONLY
///
template<typename LeftRight>
struct is_tail_variate_feature<tag::tail_weights<LeftRight>, LeftRight>
: mpl::true_
{
};
} // namespace detail
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// tail_impl
template<typename Sample, typename LeftRight>
struct tail_impl
: accumulator_base
{
// LeftRight must be either right or left
BOOST_MPL_ASSERT((
mpl::or_<is_same<LeftRight, right>, is_same<LeftRight, left> >
));
typedef
typename mpl::if_<
is_same<LeftRight, right>
, numeric::functional::greater<Sample const, Sample const>
, numeric::functional::less<Sample const, Sample const>
>::type
predicate_type;
// for boost::result_of
typedef typename detail::tail_range<
typename std::vector<Sample>::const_iterator
, std::vector<std::size_t>::iterator
>::type result_type;
template<typename Args>
tail_impl(Args const &args)
: is_sorted(false)
, indices()
, samples(args[tag::tail<LeftRight>::cache_size], args[sample | Sample()])
{
this->indices.reserve(this->samples.size());
}
tail_impl(tail_impl const &that)
: is_sorted(that.is_sorted)
, indices(that.indices)
, samples(that.samples)
{
this->indices.reserve(this->samples.size());
}
// This just stores the heap and the samples.
// In operator()() below, if we are adding a new sample
// to the sample cache, we force all the
// tail_variates to update also. (It's not
// good enough to wait for the accumulator_set to do it
// for us because then information about whether a sample
// was stored and where is lost, and would need to be
// queried at runtime, which would be slow.) This is
// implemented as a filtered visitation over the stats,
// which we can access because args[accumulator] gives us
// all the stats.
template<typename Args>
void operator ()(Args const &args)
{
if(this->indices.size() < this->samples.size())
{
this->indices.push_back(this->indices.size());
this->assign(args, this->indices.back());
}
else if(predicate_type()(args[sample], this->samples[this->indices[0]]))
{
std::pop_heap(this->indices.begin(), this->indices.end(), indirect_cmp(this->samples));
this->assign(args, this->indices.back());
}
}
result_type result(dont_care) const
{
if(!this->is_sorted)
{
// Must use the same predicate here as in push_heap/pop_heap above.
std::sort_heap(this->indices.begin(), this->indices.end(), indirect_cmp(this->samples));
// sort_heap puts elements in reverse order. Calling std::reverse
// turns the sorted sequence back into a valid heap.
std::reverse(this->indices.begin(), this->indices.end());
this->is_sorted = true;
}
return detail::make_tail_range(
this->samples.begin()
, this->indices.begin()
, this->indices.end()
);
}
private:
struct is_tail_variate
{
template<typename T>
struct apply
: detail::is_tail_variate_feature<
typename detail::feature_tag<T>::type
, LeftRight
>
{};
};
template<typename Args>
void assign(Args const &args, std::size_t index)
{
BOOST_ASSERT(index < this->samples.size());
this->samples[index] = args[sample];
std::push_heap(this->indices.begin(), this->indices.end(), indirect_cmp(this->samples));
this->is_sorted = false;
// Tell the tail variates to store their values also
args[accumulator].template visit_if<is_tail_variate>(detail::stat_assign(args, index));
}
///////////////////////////////////////////////////////////////////////////////
//
struct indirect_cmp
{
typedef std::size_t first_argument_type;
typedef std::size_t second_argument_type;
typedef bool result_type;
indirect_cmp(std::vector<Sample> const &s)
: samples(s)
{
}
bool operator ()(std::size_t left, std::size_t right) const
{
return predicate_type()(this->samples[left], this->samples[right]);
}
private:
BOOST_DELETED_FUNCTION(indirect_cmp &operator =(indirect_cmp const &))
std::vector<Sample> const &samples;
};
public:
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & is_sorted;
ar & indices;
ar & samples;
}
private:
mutable bool is_sorted;
mutable std::vector<std::size_t> indices;
std::vector<Sample> samples;
};
} // namespace impl
// TODO The templatized tag::tail below should inherit from the correct named parameter.
// The following lines provide a workaround, but there must be a better way of doing this.
template<typename T>
struct tail_cache_size_named_arg
{
};
template<>
struct tail_cache_size_named_arg<left>
: tag::left_tail_cache_size
{
};
template<>
struct tail_cache_size_named_arg<right>
: tag::right_tail_cache_size
{
};
///////////////////////////////////////////////////////////////////////////////
// tag::tail<>
//
namespace tag
{
template<typename LeftRight>
struct tail
: depends_on<>
, tail_cache_size_named_arg<LeftRight>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::tail_impl<mpl::_1, LeftRight> impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
/// tag::tail<LeftRight>::cache_size named parameter
static boost::parameter::keyword<tail_cache_size_named_arg<LeftRight> > const cache_size;
#endif
};
struct abstract_tail
: depends_on<>
{
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::tail
//
namespace extract
{
extractor<tag::abstract_tail> const tail = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(tail)
}
using extract::tail;
template<typename LeftRight>
struct feature_of<tag::tail<LeftRight> >
: feature_of<tag::abstract_tail>
{
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,254 @@
///////////////////////////////////////////////////////////////////////////////
// tail_mean.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_TAIL_MEAN_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_TAIL_MEAN_HPP_DE_01_01_2006
#include <numeric>
#include <vector>
#include <limits>
#include <functional>
#include <sstream>
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/tail.hpp>
#include <boost/accumulators/statistics/tail_quantile.hpp>
#include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// coherent_tail_mean_impl
//
/**
@brief Estimation of the coherent tail mean based on order statistics (for both left and right tails)
The coherent tail mean \f$\widehat{CTM}_{n,\alpha}(X)\f$ is equal to the non-coherent tail mean \f$\widehat{NCTM}_{n,\alpha}(X)\f$
plus a correction term that ensures coherence in case of non-continuous distributions.
\f[
\widehat{CTM}_{n,\alpha}^{\mathrm{right}}(X) = \widehat{NCTM}_{n,\alpha}^{\mathrm{right}}(X) +
\frac{1}{\lceil n(1-\alpha)\rceil}\hat{q}_{n,\alpha}(X)\left(1 - \alpha - \frac{1}{n}\lceil n(1-\alpha)\rceil \right)
\f]
\f[
\widehat{CTM}_{n,\alpha}^{\mathrm{left}}(X) = \widehat{NCTM}_{n,\alpha}^{\mathrm{left}}(X) +
\frac{1}{\lceil n\alpha\rceil}\hat{q}_{n,\alpha}(X)\left(\alpha - \frac{1}{n}\lceil n\alpha\rceil \right)
\f]
*/
template<typename Sample, typename LeftRight>
struct coherent_tail_mean_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
// for boost::result_of
typedef float_type result_type;
coherent_tail_mean_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
std::size_t cnt = count(args);
std::size_t n = static_cast<std::size_t>(
std::ceil(
cnt * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] )
)
);
extractor<tag::non_coherent_tail_mean<LeftRight> > const some_non_coherent_tail_mean = {};
return some_non_coherent_tail_mean(args)
+ numeric::fdiv(quantile(args), n)
* (
( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability]
- numeric::fdiv(n, count(args))
);
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {}
};
///////////////////////////////////////////////////////////////////////////////
// non_coherent_tail_mean_impl
//
/**
@brief Estimation of the (non-coherent) tail mean based on order statistics (for both left and right tails)
An estimation of the non-coherent tail mean \f$\widehat{NCTM}_{n,\alpha}(X)\f$ is given by the mean of the
\f$\lceil n\alpha\rceil\f$ smallest samples (left tail) or the mean of the \f$\lceil n(1-\alpha)\rceil\f$
largest samples (right tail), \f$n\f$ being the total number of samples and \f$\alpha\f$ the quantile level:
\f[
\widehat{NCTM}_{n,\alpha}^{\mathrm{right}}(X) = \frac{1}{\lceil n(1-\alpha)\rceil} \sum_{i=\lceil \alpha n \rceil}^n X_{i:n}
\f]
\f[
\widehat{NCTM}_{n,\alpha}^{\mathrm{left}}(X) = \frac{1}{\lceil n\alpha\rceil} \sum_{i=1}^{\lceil \alpha n \rceil} X_{i:n}
\f]
It thus requires the caching of at least the \f$\lceil n\alpha\rceil\f$ smallest or the \f$\lceil n(1-\alpha)\rceil\f$
largest samples.
@param quantile_probability
*/
template<typename Sample, typename LeftRight>
struct non_coherent_tail_mean_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
// for boost::result_of
typedef float_type result_type;
non_coherent_tail_mean_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
std::size_t cnt = count(args);
std::size_t n = static_cast<std::size_t>(
std::ceil(
cnt * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] )
)
);
// If n is in a valid range, return result, otherwise return NaN or throw exception
if (n <= static_cast<std::size_t>(tail(args).size()))
return numeric::fdiv(
std::accumulate(
tail(args).begin()
, tail(args).begin() + n
, Sample(0)
)
, n
);
else
{
if (std::numeric_limits<result_type>::has_quiet_NaN)
{
return std::numeric_limits<result_type>::quiet_NaN();
}
else
{
std::ostringstream msg;
msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
boost::throw_exception(std::runtime_error(msg.str()));
return Sample(0);
}
}
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::coherent_tail_mean<>
// tag::non_coherent_tail_mean<>
//
namespace tag
{
template<typename LeftRight>
struct coherent_tail_mean
: depends_on<count, quantile, non_coherent_tail_mean<LeftRight> >
{
typedef accumulators::impl::coherent_tail_mean_impl<mpl::_1, LeftRight> impl;
};
template<typename LeftRight>
struct non_coherent_tail_mean
: depends_on<count, tail<LeftRight> >
{
typedef accumulators::impl::non_coherent_tail_mean_impl<mpl::_1, LeftRight> impl;
};
struct abstract_non_coherent_tail_mean
: depends_on<>
{
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::non_coherent_tail_mean;
// extract::coherent_tail_mean;
//
namespace extract
{
extractor<tag::abstract_non_coherent_tail_mean> const non_coherent_tail_mean = {};
extractor<tag::tail_mean> const coherent_tail_mean = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(non_coherent_tail_mean)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(coherent_tail_mean)
}
using extract::non_coherent_tail_mean;
using extract::coherent_tail_mean;
// for the purposes of feature-based dependency resolution,
// coherent_tail_mean<LeftRight> provides the same feature as tail_mean
template<typename LeftRight>
struct feature_of<tag::coherent_tail_mean<LeftRight> >
: feature_of<tag::tail_mean>
{
};
template<typename LeftRight>
struct feature_of<tag::non_coherent_tail_mean<LeftRight> >
: feature_of<tag::abstract_non_coherent_tail_mean>
{
};
// So that non_coherent_tail_mean can be automatically substituted
// with weighted_non_coherent_tail_mean when the weight parameter is non-void.
template<typename LeftRight>
struct as_weighted_feature<tag::non_coherent_tail_mean<LeftRight> >
{
typedef tag::non_coherent_weighted_tail_mean<LeftRight> type;
};
template<typename LeftRight>
struct feature_of<tag::non_coherent_weighted_tail_mean<LeftRight> >
: feature_of<tag::non_coherent_tail_mean<LeftRight> >
{};
// NOTE that non_coherent_tail_mean cannot be feature-grouped with tail_mean,
// which is the base feature for coherent tail means, since (at least for
// non-continuous distributions) non_coherent_tail_mean is a different measure!
}} // namespace boost::accumulators
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,162 @@
///////////////////////////////////////////////////////////////////////////////
// tail_quantile.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_TAIL_QUANTILE_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_TAIL_QUANTILE_HPP_DE_01_01_2006
#include <vector>
#include <limits>
#include <functional>
#include <sstream>
#include <stdexcept>
#include <boost/config/no_tr1/cmath.hpp> // For ceil
#include <boost/throw_exception.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/tail.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// tail_quantile_impl
// Tail quantile estimation based on order statistics
/**
@brief Tail quantile estimation based on order statistics (for both left and right tails)
The estimation of a tail quantile \f$\hat{q}\f$ with level \f$\alpha\f$ based on order statistics requires the
caching of at least the \f$\lceil n\alpha\rceil\f$ smallest or the \f$\lceil n(1-\alpha)\rceil\f$ largest samples,
\f$n\f$ being the total number of samples. The largest of the \f$\lceil n\alpha\rceil\f$ smallest samples or the
smallest of the \f$\lceil n(1-\alpha)\rceil\f$ largest samples provides an estimate for the quantile:
\f[
\hat{q}_{n,\alpha} = X_{\lceil \alpha n \rceil:n}
\f]
@param quantile_probability
*/
template<typename Sample, typename LeftRight>
struct tail_quantile_impl
: accumulator_base
{
// for boost::result_of
typedef Sample result_type;
tail_quantile_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
std::size_t cnt = count(args);
std::size_t n = static_cast<std::size_t>(
std::ceil(
cnt * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] )
)
);
// If n is in a valid range, return result, otherwise return NaN or throw exception
if ( n < static_cast<std::size_t>(tail(args).size()))
{
// Note that the cached samples of the left are sorted in ascending order,
// whereas the samples of the right tail are sorted in descending order
return *(boost::begin(tail(args)) + n - 1);
}
else
{
if (std::numeric_limits<result_type>::has_quiet_NaN)
{
return std::numeric_limits<result_type>::quiet_NaN();
}
else
{
std::ostringstream msg;
msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
boost::throw_exception(std::runtime_error(msg.str()));
return Sample(0);
}
}
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version) {}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::tail_quantile<>
//
namespace tag
{
template<typename LeftRight>
struct tail_quantile
: depends_on<count, tail<LeftRight> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::tail_quantile_impl<mpl::_1, LeftRight> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::tail_quantile
//
namespace extract
{
extractor<tag::quantile> const tail_quantile = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(tail_quantile)
}
using extract::tail_quantile;
// for the purposes of feature-based dependency resolution,
// tail_quantile<LeftRight> provide the same feature as quantile
template<typename LeftRight>
struct feature_of<tag::tail_quantile<LeftRight> >
: feature_of<tag::quantile>
{
};
// So that tail_quantile can be automatically substituted with
// weighted_tail_quantile when the weight parameter is non-void.
template<typename LeftRight>
struct as_weighted_feature<tag::tail_quantile<LeftRight> >
{
typedef tag::weighted_tail_quantile<LeftRight> type;
};
template<typename LeftRight>
struct feature_of<tag::weighted_tail_quantile<LeftRight> >
: feature_of<tag::tail_quantile<LeftRight> >
{};
}} // namespace boost::accumulators
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,150 @@
///////////////////////////////////////////////////////////////////////////////
// tail_variate.hpp
//
// Copyright 2005 Eric Niebler, Michael Gauckler. 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_STAT_STATISTICS_TAIL_VARIATE_HPP_EAN_28_10_2005
#define BOOST_STAT_STATISTICS_TAIL_VARIATE_HPP_EAN_28_10_2005
#include <boost/range.hpp>
#include <boost/mpl/always.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/iterator/reverse_iterator.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/tail.hpp>
#include <boost/serialization/vector.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// tail_variate_impl
template<typename VariateType, typename VariateTag, typename LeftRight>
struct tail_variate_impl
: accumulator_base
{
// for boost::result_of
typedef
typename detail::tail_range<
typename std::vector<VariateType>::const_iterator
, std::vector<std::size_t>::iterator
>::type
result_type;
template<typename Args>
tail_variate_impl(Args const &args)
: variates(args[tag::tail<LeftRight>::cache_size], args[parameter::keyword<VariateTag>::get() | VariateType()])
{
}
template<typename Args>
void assign(Args const &args, std::size_t index)
{
this->variates[index] = args[parameter::keyword<VariateTag>::get()];
}
template<typename Args>
result_type result(Args const &args) const
{
// getting the order result causes the indices vector to be sorted.
extractor<tag::tail<LeftRight> > const some_tail = {};
return this->do_result(some_tail(args));
}
private:
template<typename TailRng>
result_type do_result(TailRng const &rng) const
{
return detail::make_tail_range(
this->variates.begin()
, rng.end().base().base() // the index iterator
, rng.begin().base().base() // (begin and end reversed because these are reverse iterators)
);
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & variates;
}
private:
std::vector<VariateType> variates;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::tail_variate<>
//
namespace tag
{
template<typename VariateType, typename VariateTag, typename LeftRight>
struct tail_variate
: depends_on<tail<LeftRight> >
{
/// INTERNAL ONLY
///
typedef mpl::always<accumulators::impl::tail_variate_impl<VariateType, VariateTag, LeftRight> > impl;
};
struct abstract_tail_variate
: depends_on<>
{
};
template<typename LeftRight>
struct tail_weights
: depends_on<tail<LeftRight> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::tail_variate_impl<mpl::_2, tag::weight, LeftRight> impl;
};
struct abstract_tail_weights
: depends_on<>
{
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::tail_variate
// extract::tail_weights
//
namespace extract
{
extractor<tag::abstract_tail_variate> const tail_variate = {};
extractor<tag::abstract_tail_weights> const tail_weights = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(tail_variate)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(tail_weights)
}
using extract::tail_variate;
using extract::tail_weights;
template<typename VariateType, typename VariateTag, typename LeftRight>
struct feature_of<tag::tail_variate<VariateType, VariateTag, LeftRight> >
: feature_of<tag::abstract_tail_variate>
{
};
template<typename LeftRight>
struct feature_of<tag::tail_weights<LeftRight> >
{
typedef tag::abstract_tail_weights type;
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,270 @@
///////////////////////////////////////////////////////////////////////////////
// tail_variate_means.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_TAIL_VARIATE_MEANS_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_TAIL_VARIATE_MEANS_HPP_DE_01_01_2006
#include <numeric>
#include <vector>
#include <limits>
#include <functional>
#include <sstream>
#include <stdexcept>
#include <boost/throw_exception.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/tail.hpp>
#include <boost/accumulators/statistics/tail_variate.hpp>
#include <boost/accumulators/statistics/tail_mean.hpp>
#include <boost/accumulators/statistics/parameters/quantile_probability.hpp>
#include <boost/serialization/vector.hpp>
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
#endif
namespace boost { namespace accumulators
{
namespace impl
{
/**
@brief Estimation of the absolute and relative tail variate means (for both left and right tails)
For all \f$j\f$-th variates associated to the \f$\lceil n(1-\alpha)\rceil\f$ largest samples (or the
\f$\lceil n(1-\alpha)\rceil\f$ smallest samples in case of the left tail), the absolute tail means
\f$\widehat{ATM}_{n,\alpha}(X, j)\f$ are computed and returned as an iterator range. Alternatively,
the relative tail means \f$\widehat{RTM}_{n,\alpha}(X, j)\f$ are returned, which are the absolute
tail means normalized with the (non-coherent) sample tail mean \f$\widehat{NCTM}_{n,\alpha}(X)\f$.
\f[
\widehat{ATM}_{n,\alpha}^{\mathrm{right}}(X, j) =
\frac{1}{\lceil n(1-\alpha) \rceil}
\sum_{i=\lceil \alpha n \rceil}^n \xi_{j,i}
\f]
\f[
\widehat{ATM}_{n,\alpha}^{\mathrm{left}}(X, j) =
\frac{1}{\lceil n\alpha \rceil}
\sum_{i=1}^{\lceil n\alpha \rceil} \xi_{j,i}
\f]
\f[
\widehat{RTM}_{n,\alpha}^{\mathrm{right}}(X, j) =
\frac{\sum_{i=\lceil n\alpha \rceil}^n \xi_{j,i}}
{\lceil n(1-\alpha)\rceil\widehat{NCTM}_{n,\alpha}^{\mathrm{right}}(X)}
\f]
\f[
\widehat{RTM}_{n,\alpha}^{\mathrm{left}}(X, j) =
\frac{\sum_{i=1}^{\lceil n\alpha \rceil} \xi_{j,i}}
{\lceil n\alpha\rceil\widehat{NCTM}_{n,\alpha}^{\mathrm{left}}(X)}
\f]
*/
///////////////////////////////////////////////////////////////////////////////
// tail_variate_means_impl
// by default: absolute tail_variate_means
template<typename Sample, typename Impl, typename LeftRight, typename VariateTag>
struct tail_variate_means_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
typedef std::vector<float_type> array_type;
// for boost::result_of
typedef iterator_range<typename array_type::iterator> result_type;
tail_variate_means_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
std::size_t cnt = count(args);
std::size_t n = static_cast<std::size_t>(
std::ceil(
cnt * ( ( is_same<LeftRight, left>::value ) ? args[quantile_probability] : 1. - args[quantile_probability] )
)
);
std::size_t num_variates = tail_variate(args).begin()->size();
this->tail_means_.clear();
this->tail_means_.resize(num_variates, Sample(0));
// If n is in a valid range, return result, otherwise return NaN or throw exception
if (n < static_cast<std::size_t>(tail(args).size()))
{
this->tail_means_ = std::accumulate(
tail_variate(args).begin()
, tail_variate(args).begin() + n
, this->tail_means_
, numeric::plus
);
float_type factor = n * ( (is_same<Impl, relative>::value) ? non_coherent_tail_mean(args) : 1. );
std::transform(
this->tail_means_.begin()
, this->tail_means_.end()
, this->tail_means_.begin()
#ifdef BOOST_NO_CXX98_BINDERS
, std::bind(std::divides<float_type>(), std::placeholders::_1, factor)
#else
, std::bind2nd(std::divides<float_type>(), factor)
#endif
);
}
else
{
if (std::numeric_limits<float_type>::has_quiet_NaN)
{
std::fill(
this->tail_means_.begin()
, this->tail_means_.end()
, std::numeric_limits<float_type>::quiet_NaN()
);
}
else
{
std::ostringstream msg;
msg << "index n = " << n << " is not in valid range [0, " << tail(args).size() << ")";
boost::throw_exception(std::runtime_error(msg.str()));
}
}
return make_iterator_range(this->tail_means_);
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & tail_means_;
}
private:
mutable array_type tail_means_;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::absolute_tail_variate_means
// tag::relative_tail_variate_means
//
namespace tag
{
template<typename LeftRight, typename VariateType, typename VariateTag>
struct absolute_tail_variate_means
: depends_on<count, non_coherent_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight> >
{
typedef accumulators::impl::tail_variate_means_impl<mpl::_1, absolute, LeftRight, VariateTag> impl;
};
template<typename LeftRight, typename VariateType, typename VariateTag>
struct relative_tail_variate_means
: depends_on<count, non_coherent_tail_mean<LeftRight>, tail_variate<VariateType, VariateTag, LeftRight> >
{
typedef accumulators::impl::tail_variate_means_impl<mpl::_1, relative, LeftRight, VariateTag> impl;
};
struct abstract_absolute_tail_variate_means
: depends_on<>
{
};
struct abstract_relative_tail_variate_means
: depends_on<>
{
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::tail_variate_means
// extract::relative_tail_variate_means
//
namespace extract
{
extractor<tag::abstract_absolute_tail_variate_means> const tail_variate_means = {};
extractor<tag::abstract_relative_tail_variate_means> const relative_tail_variate_means = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(tail_variate_means)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(relative_tail_variate_means)
}
using extract::tail_variate_means;
using extract::relative_tail_variate_means;
// tail_variate_means<LeftRight, VariateType, VariateTag>(absolute) -> absolute_tail_variate_means<LeftRight, VariateType, VariateTag>
template<typename LeftRight, typename VariateType, typename VariateTag>
struct as_feature<tag::tail_variate_means<LeftRight, VariateType, VariateTag>(absolute)>
{
typedef tag::absolute_tail_variate_means<LeftRight, VariateType, VariateTag> type;
};
// tail_variate_means<LeftRight, VariateType, VariateTag>(relative) ->relative_tail_variate_means<LeftRight, VariateType, VariateTag>
template<typename LeftRight, typename VariateType, typename VariateTag>
struct as_feature<tag::tail_variate_means<LeftRight, VariateType, VariateTag>(relative)>
{
typedef tag::relative_tail_variate_means<LeftRight, VariateType, VariateTag> type;
};
// Provides non-templatized extractor
template<typename LeftRight, typename VariateType, typename VariateTag>
struct feature_of<tag::absolute_tail_variate_means<LeftRight, VariateType, VariateTag> >
: feature_of<tag::abstract_absolute_tail_variate_means>
{
};
// Provides non-templatized extractor
template<typename LeftRight, typename VariateType, typename VariateTag>
struct feature_of<tag::relative_tail_variate_means<LeftRight, VariateType, VariateTag> >
: feature_of<tag::abstract_relative_tail_variate_means>
{
};
// So that absolute_tail_means can be automatically substituted
// with absolute_weighted_tail_means when the weight parameter is non-void.
template<typename LeftRight, typename VariateType, typename VariateTag>
struct as_weighted_feature<tag::absolute_tail_variate_means<LeftRight, VariateType, VariateTag> >
{
typedef tag::absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
};
template<typename LeftRight, typename VariateType, typename VariateTag>
struct feature_of<tag::absolute_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> >
: feature_of<tag::absolute_tail_variate_means<LeftRight, VariateType, VariateTag> >
{
};
// So that relative_tail_means can be automatically substituted
// with relative_weighted_tail_means when the weight parameter is non-void.
template<typename LeftRight, typename VariateType, typename VariateTag>
struct as_weighted_feature<tag::relative_tail_variate_means<LeftRight, VariateType, VariateTag> >
{
typedef tag::relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> type;
};
template<typename LeftRight, typename VariateType, typename VariateTag>
struct feature_of<tag::relative_weighted_tail_variate_means<LeftRight, VariateType, VariateTag> >
: feature_of<tag::relative_tail_variate_means<LeftRight, VariateType, VariateTag> >
{
};
}} // namespace boost::accumulators
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#endif
@@ -0,0 +1,70 @@
///////////////////////////////////////////////////////////////////////////////
// times2_iterator.hpp
//
// Copyright 2006 Eric Niebler. 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_ACCUMULATORS_STATISTICS_TIMES2_ITERATOR_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_TIMES2_ITERATOR_HPP_DE_01_01_2006
#include <functional>
#include <boost/detail/workaround.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/iterator/permutation_iterator.hpp>
namespace boost { namespace accumulators
{
namespace detail
{
typedef transform_iterator<
#ifdef BOOST_NO_CXX98_BINDERS
decltype(std::bind(std::multiplies<std::size_t>(), 2, std::placeholders::_1))
#else
std::binder1st<std::multiplies<std::size_t> >
#endif
, counting_iterator<std::size_t>
> times2_iterator;
inline times2_iterator make_times2_iterator(std::size_t i)
{
return make_transform_iterator(
make_counting_iterator(i)
#ifdef BOOST_NO_CXX98_BINDERS
, std::bind(std::multiplies<std::size_t>(), 2, std::placeholders::_1)
#else
, std::bind1st(std::multiplies<std::size_t>(), 2)
#endif
);
}
///////////////////////////////////////////////////////////////////////////////
// lvalue_index_iterator
template<typename Base>
struct lvalue_index_iterator
: Base
{
lvalue_index_iterator()
: Base()
{}
lvalue_index_iterator(Base base)
: Base(base)
{
}
typename Base::reference operator [](typename Base::difference_type n) const
{
return *(*this + n);
}
};
} // namespace detail
}}
#endif
@@ -0,0 +1,247 @@
///////////////////////////////////////////////////////////////////////////////
// variance.hpp
//
// Copyright 2005 Daniel Egloff, Eric Niebler. 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_ACCUMULATORS_STATISTICS_VARIANCE_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_VARIANCE_HPP_EAN_28_10_2005
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/moment.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
//! Lazy calculation of variance.
/*!
Default sample variance implementation based on the second moment \f$ M_n^{(2)} \f$ moment<2>, mean and count.
\f[
\sigma_n^2 = M_n^{(2)} - \mu_n^2.
\f]
where
\f[
\mu_n = \frac{1}{n} \sum_{i = 1}^n x_i.
\f]
is the estimate of the sample mean and \f$n\f$ is the number of samples.
*/
template<typename Sample, typename MeanFeature>
struct lazy_variance_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
lazy_variance_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
extractor<MeanFeature> mean;
result_type tmp = mean(args);
return accumulators::moment<2>(args) - tmp * tmp;
}
// serialization is done by accumulators it depends on
template<class Archive>
void serialize(Archive & /* ar */, const unsigned int /* file_version */) {}
};
//! Iterative calculation of variance.
/*!
Iterative calculation of sample variance \f$\sigma_n^2\f$ according to the formula
\f[
\sigma_n^2 = \frac{1}{n} \sum_{i = 1}^n (x_i - \mu_n)^2 = \frac{n-1}{n} \sigma_{n-1}^2 + \frac{1}{n-1}(x_n - \mu_n)^2.
\f]
where
\f[
\mu_n = \frac{1}{n} \sum_{i = 1}^n x_i.
\f]
is the estimate of the sample mean and \f$n\f$ is the number of samples.
Note that the sample variance is not defined for \f$n <= 1\f$.
A simplification can be obtained by the approximate recursion
\f[
\sigma_n^2 \approx \frac{n-1}{n} \sigma_{n-1}^2 + \frac{1}{n}(x_n - \mu_n)^2.
\f]
because the difference
\f[
\left(\frac{1}{n-1} - \frac{1}{n}\right)(x_n - \mu_n)^2 = \frac{1}{n(n-1)}(x_n - \mu_n)^2.
\f]
converges to zero as \f$n \rightarrow \infty\f$. However, for small \f$ n \f$ the difference
can be non-negligible.
*/
template<typename Sample, typename MeanFeature, typename Tag>
struct variance_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
template<typename Args>
variance_impl(Args const &args)
: variance(numeric::fdiv(args[sample | Sample()], numeric::one<std::size_t>::value))
{
}
template<typename Args>
void operator ()(Args const &args)
{
std::size_t cnt = count(args);
if(cnt > 1)
{
extractor<MeanFeature> mean;
result_type tmp = args[parameter::keyword<Tag>::get()] - mean(args);
this->variance =
numeric::fdiv(this->variance * (cnt - 1), cnt)
+ numeric::fdiv(tmp * tmp, cnt - 1);
}
}
result_type result(dont_care) const
{
return this->variance;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */)
{
ar & variance;
}
private:
result_type variance;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::variance
// tag::immediate_variance
//
namespace tag
{
struct lazy_variance
: depends_on<moment<2>, mean>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::lazy_variance_impl<mpl::_1, mean> impl;
};
struct variance
: depends_on<count, immediate_mean>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::variance_impl<mpl::_1, mean, sample> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::lazy_variance
// extract::variance
//
namespace extract
{
extractor<tag::lazy_variance> const lazy_variance = {};
extractor<tag::variance> const variance = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(lazy_variance)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(variance)
}
using extract::lazy_variance;
using extract::variance;
// variance(lazy) -> lazy_variance
template<>
struct as_feature<tag::variance(lazy)>
{
typedef tag::lazy_variance type;
};
// variance(immediate) -> variance
template<>
struct as_feature<tag::variance(immediate)>
{
typedef tag::variance type;
};
// for the purposes of feature-based dependency resolution,
// immediate_variance provides the same feature as variance
template<>
struct feature_of<tag::lazy_variance>
: feature_of<tag::variance>
{
};
// So that variance can be automatically substituted with
// weighted_variance when the weight parameter is non-void.
template<>
struct as_weighted_feature<tag::variance>
{
typedef tag::weighted_variance type;
};
// for the purposes of feature-based dependency resolution,
// weighted_variance provides the same feature as variance
template<>
struct feature_of<tag::weighted_variance>
: feature_of<tag::variance>
{
};
// So that immediate_variance can be automatically substituted with
// immediate_weighted_variance when the weight parameter is non-void.
template<>
struct as_weighted_feature<tag::lazy_variance>
{
typedef tag::lazy_weighted_variance type;
};
// for the purposes of feature-based dependency resolution,
// immediate_weighted_variance provides the same feature as immediate_variance
template<>
struct feature_of<tag::lazy_weighted_variance>
: feature_of<tag::lazy_variance>
{
};
////////////////////////////////////////////////////////////////////////////
//// droppable_accumulator<variance_impl>
//// need to specialize droppable lazy variance to cache the result at the
//// point the accumulator is dropped.
///// INTERNAL ONLY
/////
//template<typename Sample, typename MeanFeature>
//struct droppable_accumulator<impl::variance_impl<Sample, MeanFeature> >
// : droppable_accumulator_base<
// with_cached_result<impl::variance_impl<Sample, MeanFeature> >
// >
//{
// template<typename Args>
// droppable_accumulator(Args const &args)
// : droppable_accumulator::base(args)
// {
// }
//};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,25 @@
///////////////////////////////////////////////////////////////////////////////
// weight.hpp
//
// Copyright 2005 Eric Niebler. 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_ACCUMULATORS_STATISTICS_VARIATES_COVARIATE_HPP_EAN_03_11_2005
#define BOOST_ACCUMULATORS_STATISTICS_VARIATES_COVARIATE_HPP_EAN_03_11_2005
#include <boost/parameter/keyword.hpp>
#include <boost/accumulators/accumulators_fwd.hpp>
namespace boost { namespace accumulators
{
BOOST_PARAMETER_KEYWORD(tag, covariate1)
BOOST_PARAMETER_KEYWORD(tag, covariate2)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(covariate1)
BOOST_ACCUMULATORS_IGNORE_GLOBAL(covariate2)
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,140 @@
///////////////////////////////////////////////////////////////////////////////
// weighted_covariance.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_WEIGHTED_COVARIANCE_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_COVARIANCE_HPP_DE_01_01_2006
#include <vector>
#include <limits>
#include <numeric>
#include <functional>
#include <complex>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/range.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/type_traits/is_scalar.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/covariance.hpp> // for numeric::outer_product() and type traits
#include <boost/accumulators/statistics/weighted_mean.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// weighted_covariance_impl
//
/**
@brief Weighted Covariance Estimator
An iterative Monte Carlo estimator for the weighted covariance \f$\mathrm{Cov}(X,X')\f$, where \f$X\f$ is a sample
and \f$X'\f$ a variate, is given by:
\f[
\hat{c}_n = \frac{\bar{w}_n-w_n}{\bar{w}_n} \hat{c}_{n-1} + \frac{w_n}{\bar{w}_n-w_n}(X_n - \hat{\mu}_n)(X_n' - \hat{\mu}_n'),
\quad n\ge2,\quad\hat{c}_1 = 0,
\f]
\f$\hat{\mu}_n\f$ and \f$\hat{\mu}_n'\f$ being the weighted means of the samples and variates and
\f$\bar{w}_n\f$ the sum of the \f$n\f$ first weights \f$w_i\f$.
*/
template<typename Sample, typename Weight, typename VariateType, typename VariateTag>
struct weighted_covariance_impl
: accumulator_base
{
typedef typename numeric::functional::multiplies<Weight, typename numeric::functional::fdiv<Sample, std::size_t>::result_type>::result_type weighted_sample_type;
typedef typename numeric::functional::multiplies<Weight, typename numeric::functional::fdiv<VariateType, std::size_t>::result_type>::result_type weighted_variate_type;
// for boost::result_of
typedef typename numeric::functional::outer_product<weighted_sample_type, weighted_variate_type>::result_type result_type;
template<typename Args>
weighted_covariance_impl(Args const &args)
: cov_(
numeric::outer_product(
numeric::fdiv(args[sample | Sample()], (std::size_t)1)
* numeric::one<Weight>::value
, numeric::fdiv(args[parameter::keyword<VariateTag>::get() | VariateType()], (std::size_t)1)
* numeric::one<Weight>::value
)
)
{
}
template<typename Args>
void operator ()(Args const &args)
{
std::size_t cnt = count(args);
if (cnt > 1)
{
extractor<tag::weighted_mean_of_variates<VariateType, VariateTag> > const some_weighted_mean_of_variates = {};
this->cov_ = this->cov_ * (sum_of_weights(args) - args[weight]) / sum_of_weights(args)
+ numeric::outer_product(
some_weighted_mean_of_variates(args) - args[parameter::keyword<VariateTag>::get()]
, weighted_mean(args) - args[sample]
) * args[weight] / (sum_of_weights(args) - args[weight]);
}
}
result_type result(dont_care) const
{
return this->cov_;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & cov_;
}
private:
result_type cov_;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::weighted_covariance
//
namespace tag
{
template<typename VariateType, typename VariateTag>
struct weighted_covariance
: depends_on<count, sum_of_weights, weighted_mean, weighted_mean_of_variates<VariateType, VariateTag> >
{
typedef accumulators::impl::weighted_covariance_impl<mpl::_1, mpl::_2, VariateType, VariateTag> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::weighted_covariance
//
namespace extract
{
extractor<tag::abstract_covariance> const weighted_covariance = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_covariance)
}
using extract::weighted_covariance;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,237 @@
///////////////////////////////////////////////////////////////////////////////
// weighted_density.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_WEIGHTED_DENSITY_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_DENSITY_HPP_DE_01_01_2006
#include <vector>
#include <limits>
#include <functional>
#include <boost/range.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/max.hpp>
#include <boost/accumulators/statistics/min.hpp>
#include <boost/accumulators/statistics/density.hpp> // for named parameters density_cache_size and density_num_bins
#include <boost/serialization/vector.hpp>
#include <boost/serialization/utility.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// weighted_density_impl
// density histogram for weighted samples
/**
@brief Histogram density estimator for weighted samples
The histogram density estimator returns a histogram of the sample distribution. The positions and sizes of the bins
are determined using a specifiable number of cached samples (cache_size). The range between the minimum and the
maximum of the cached samples is subdivided into a specifiable number of bins (num_bins) of same size. Additionally,
an under- and an overflow bin is added to capture future under- and overflow samples. Once the bins are determined,
the cached samples and all subsequent samples are added to the correct bins. At the end, a range of std::pair is
returned, where each pair contains the position of the bin (lower bound) and the sum of the weights (normalized with the
sum of all weights).
@param density_cache_size Number of first samples used to determine min and max.
@param density_num_bins Number of bins (two additional bins collect under- and overflow samples).
*/
template<typename Sample, typename Weight>
struct weighted_density_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Weight, std::size_t>::result_type float_type;
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
typedef std::vector<float_type> array_type;
// for boost::result_of
typedef iterator_range<typename histogram_type::iterator> result_type;
template<typename Args>
weighted_density_impl(Args const &args)
: cache_size(args[density_cache_size])
, cache(cache_size)
, num_bins(args[density_num_bins])
, samples_in_bin(num_bins + 2, 0.)
, bin_positions(num_bins + 2)
, histogram(
num_bins + 2
, std::make_pair(
numeric::fdiv(args[sample | Sample()],(std::size_t)1)
, numeric::fdiv(args[sample | Sample()],(std::size_t)1)
)
)
, is_dirty(true)
{
}
template<typename Args>
void operator ()(Args const &args)
{
this->is_dirty = true;
std::size_t cnt = count(args);
// Fill up cache with cache_size first samples
if (cnt <= this->cache_size)
{
this->cache[cnt - 1] = std::make_pair(args[sample], args[weight]);
}
// Once cache_size samples have been accumulated, create num_bins bins of same size between
// the minimum and maximum of the cached samples as well as an under- and an overflow bin.
// Store their lower bounds (bin_positions) and fill the bins with the cached samples (samples_in_bin).
if (cnt == this->cache_size)
{
float_type minimum = numeric::fdiv((min)(args),(std::size_t)1);
float_type maximum = numeric::fdiv((max)(args),(std::size_t)1);
float_type bin_size = numeric::fdiv(maximum - minimum, this->num_bins);
// determine bin positions (their lower bounds)
for (std::size_t i = 0; i < this->num_bins + 2; ++i)
{
this->bin_positions[i] = minimum + (i - 1.) * bin_size;
}
for (typename histogram_type::const_iterator iter = this->cache.begin(); iter != this->cache.end(); ++iter)
{
if (iter->first < this->bin_positions[1])
{
this->samples_in_bin[0] += iter->second;
}
else if (iter->first >= this->bin_positions[this->num_bins + 1])
{
this->samples_in_bin[this->num_bins + 1] += iter->second;
}
else
{
typename array_type::iterator it = std::upper_bound(
this->bin_positions.begin()
, this->bin_positions.end()
, iter->first
);
std::size_t d = std::distance(this->bin_positions.begin(), it);
this->samples_in_bin[d - 1] += iter->second;
}
}
}
// Add each subsequent sample to the correct bin
else if (cnt > this->cache_size)
{
if (args[sample] < this->bin_positions[1])
{
this->samples_in_bin[0] += args[weight];
}
else if (args[sample] >= this->bin_positions[this->num_bins + 1])
{
this->samples_in_bin[this->num_bins + 1] += args[weight];
}
else
{
typename array_type::iterator it = std::upper_bound(
this->bin_positions.begin()
, this->bin_positions.end()
, args[sample]
);
std::size_t d = std::distance(this->bin_positions.begin(), it);
this->samples_in_bin[d - 1] += args[weight];
}
}
}
template<typename Args>
result_type result(Args const &args) const
{
if (this->is_dirty)
{
this->is_dirty = false;
// creates a vector of std::pair where each pair i holds
// the values bin_positions[i] (x-axis of histogram) and
// samples_in_bin[i] / cnt (y-axis of histogram).
for (std::size_t i = 0; i < this->num_bins + 2; ++i)
{
this->histogram[i] = std::make_pair(this->bin_positions[i], numeric::fdiv(this->samples_in_bin[i], sum_of_weights(args)));
}
}
// returns a range of pairs
return make_iterator_range(this->histogram);
}
// make this accumulator serializeable
// TODO split to save/load and check on parameters provided in ctor
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & cache_size;
ar & cache;
ar & num_bins;
ar & samples_in_bin;
ar & bin_positions;
ar & histogram;
ar & is_dirty;
}
private:
std::size_t cache_size; // number of cached samples
histogram_type cache; // cache to store the first cache_size samples with their weights as std::pair
std::size_t num_bins; // number of bins
array_type samples_in_bin; // number of samples in each bin
array_type bin_positions; // lower bounds of bins
mutable histogram_type histogram; // histogram
mutable bool is_dirty;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::weighted_density
//
namespace tag
{
struct weighted_density
: depends_on<count, sum_of_weights, min, max>
, density_cache_size
, density_num_bins
{
/// INTERNAL ONLY
///
typedef accumulators::impl::weighted_density_impl<mpl::_1, mpl::_2> impl;
#ifdef BOOST_ACCUMULATORS_DOXYGEN_INVOKED
static boost::parameter::keyword<density_cache_size> const cache_size;
static boost::parameter::keyword<density_num_bins> const num_bins;
#endif
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::weighted_density
//
namespace extract
{
extractor<tag::density> const weighted_density = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_density)
}
using extract::weighted_density;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,302 @@
///////////////////////////////////////////////////////////////////////////////
// weighted_extended_p_square.hpp
//
// Copyright 2005 Daniel Egloff. 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_ACCUMULATORS_STATISTICS_WEIGHTED_EXTENDED_P_SQUARE_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_EXTENDED_P_SQUARE_HPP_DE_01_01_2006
#include <vector>
#include <functional>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/times2_iterator.hpp>
#include <boost/accumulators/statistics/extended_p_square.hpp>
#include <boost/serialization/vector.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// weighted_extended_p_square_impl
// multiple quantile estimation with weighted samples
/**
@brief Multiple quantile estimation with the extended \f$P^2\f$ algorithm for weighted samples
This version of the extended \f$P^2\f$ algorithm extends the extended \f$P^2\f$ algorithm to
support weighted samples. The extended \f$P^2\f$ algorithm dynamically estimates several
quantiles without storing samples. Assume that \f$m\f$ quantiles
\f$\xi_{p_1}, \ldots, \xi_{p_m}\f$ are to be estimated. Instead of storing the whole sample
cumulative distribution, the algorithm maintains only \f$m+2\f$ principal markers and
\f$m+1\f$ middle markers, whose positions are updated with each sample and whose heights
are adjusted (if necessary) using a piecewise-parablic formula. The heights of the principal
markers are the current estimates of the quantiles and are returned as an iterator range.
For further details, see
K. E. E. Raatikainen, Simultaneous estimation of several quantiles, Simulation, Volume 49,
Number 4 (October), 1986, p. 159-164.
The extended \f$ P^2 \f$ algorithm generalizes the \f$ P^2 \f$ algorithm of
R. Jain and I. Chlamtac, The P^2 algorithm for dynamic calculation of quantiles and
histograms without storing observations, Communications of the ACM,
Volume 28 (October), Number 10, 1985, p. 1076-1085.
@param extended_p_square_probabilities A vector of quantile probabilities.
*/
template<typename Sample, typename Weight>
struct weighted_extended_p_square_impl
: accumulator_base
{
typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
typedef typename numeric::functional::fdiv<weighted_sample, std::size_t>::result_type float_type;
typedef std::vector<float_type> array_type;
// for boost::result_of
typedef iterator_range<
detail::lvalue_index_iterator<
permutation_iterator<
typename array_type::const_iterator
, detail::times2_iterator
>
>
> result_type;
template<typename Args>
weighted_extended_p_square_impl(Args const &args)
: probabilities(
boost::begin(args[extended_p_square_probabilities])
, boost::end(args[extended_p_square_probabilities])
)
, heights(2 * probabilities.size() + 3)
, actual_positions(heights.size())
, desired_positions(heights.size())
{
}
template<typename Args>
void operator ()(Args const &args)
{
std::size_t cnt = count(args);
std::size_t sample_cell = 1; // k
std::size_t num_quantiles = this->probabilities.size();
// m+2 principal markers and m+1 middle markers
std::size_t num_markers = 2 * num_quantiles + 3;
// first accumulate num_markers samples
if(cnt <= num_markers)
{
this->heights[cnt - 1] = args[sample];
this->actual_positions[cnt - 1] = args[weight];
// complete the initialization of heights (and actual_positions) by sorting
if(cnt == num_markers)
{
// TODO: we need to sort the initial samples (in heights) in ascending order and
// sort their weights (in actual_positions) the same way. The following lines do
// it, but there must be a better and more efficient way of doing this.
typename array_type::iterator it_begin, it_end, it_min;
it_begin = this->heights.begin();
it_end = this->heights.end();
std::size_t pos = 0;
while (it_begin != it_end)
{
it_min = std::min_element(it_begin, it_end);
std::size_t d = std::distance(it_begin, it_min);
std::swap(*it_begin, *it_min);
std::swap(this->actual_positions[pos], this->actual_positions[pos + d]);
++it_begin;
++pos;
}
// calculate correct initial actual positions
for (std::size_t i = 1; i < num_markers; ++i)
{
actual_positions[i] += actual_positions[i - 1];
}
}
}
else
{
if(args[sample] < this->heights[0])
{
this->heights[0] = args[sample];
this->actual_positions[0] = args[weight];
sample_cell = 1;
}
else if(args[sample] >= this->heights[num_markers - 1])
{
this->heights[num_markers - 1] = args[sample];
sample_cell = num_markers - 1;
}
else
{
// find cell k = sample_cell such that heights[k-1] <= sample < heights[k]
typedef typename array_type::iterator iterator;
iterator it = std::upper_bound(
this->heights.begin()
, this->heights.end()
, args[sample]
);
sample_cell = std::distance(this->heights.begin(), it);
}
// update actual position of all markers above sample_cell
for(std::size_t i = sample_cell; i < num_markers; ++i)
{
this->actual_positions[i] += args[weight];
}
// compute desired positions
{
this->desired_positions[0] = this->actual_positions[0];
this->desired_positions[num_markers - 1] = sum_of_weights(args);
this->desired_positions[1] = (sum_of_weights(args) - this->actual_positions[0]) * probabilities[0]
/ 2. + this->actual_positions[0];
this->desired_positions[num_markers - 2] = (sum_of_weights(args) - this->actual_positions[0])
* (probabilities[num_quantiles - 1] + 1.)
/ 2. + this->actual_positions[0];
for (std::size_t i = 0; i < num_quantiles; ++i)
{
this->desired_positions[2 * i + 2] = (sum_of_weights(args) - this->actual_positions[0])
* probabilities[i] + this->actual_positions[0];
}
for (std::size_t i = 1; i < num_quantiles; ++i)
{
this->desired_positions[2 * i + 1] = (sum_of_weights(args) - this->actual_positions[0])
* (probabilities[i - 1] + probabilities[i])
/ 2. + this->actual_positions[0];
}
}
// adjust heights and actual_positions of markers 1 to num_markers - 2 if necessary
for (std::size_t i = 1; i <= num_markers - 2; ++i)
{
// offset to desired position
float_type d = this->desired_positions[i] - this->actual_positions[i];
// offset to next position
float_type dp = this->actual_positions[i + 1] - this->actual_positions[i];
// offset to previous position
float_type dm = this->actual_positions[i - 1] - this->actual_positions[i];
// height ds
float_type hp = (this->heights[i + 1] - this->heights[i]) / dp;
float_type hm = (this->heights[i - 1] - this->heights[i]) / dm;
if((d >= 1 && dp > 1) || (d <= -1 && dm < -1))
{
short sign_d = static_cast<short>(d / std::abs(d));
float_type h = this->heights[i] + sign_d / (dp - dm) * ((sign_d - dm)*hp + (dp - sign_d) * hm);
// try adjusting heights[i] using p-squared formula
if(this->heights[i - 1] < h && h < this->heights[i + 1])
{
this->heights[i] = h;
}
else
{
// use linear formula
if(d > 0)
{
this->heights[i] += hp;
}
if(d < 0)
{
this->heights[i] -= hm;
}
}
this->actual_positions[i] += sign_d;
}
}
}
}
result_type result(dont_care) const
{
// for i in [1,probabilities.size()], return heights[i * 2]
detail::times2_iterator idx_begin = detail::make_times2_iterator(1);
detail::times2_iterator idx_end = detail::make_times2_iterator(this->probabilities.size() + 1);
return result_type(
make_permutation_iterator(this->heights.begin(), idx_begin)
, make_permutation_iterator(this->heights.begin(), idx_end)
);
}
// make this accumulator serializeable
// TODO: do we need to split to load/save and verify that the parameters did not change?
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & probabilities;
ar & heights;
ar & actual_positions;
ar & desired_positions;
}
private:
array_type probabilities; // the quantile probabilities
array_type heights; // q_i
array_type actual_positions; // n_i
array_type desired_positions; // d_i
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::weighted_extended_p_square
//
namespace tag
{
struct weighted_extended_p_square
: depends_on<count, sum_of_weights>
, extended_p_square_probabilities
{
typedef accumulators::impl::weighted_extended_p_square_impl<mpl::_1, mpl::_2> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::weighted_extended_p_square
//
namespace extract
{
extractor<tag::weighted_extended_p_square> const weighted_extended_p_square = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_extended_p_square)
}
using extract::weighted_extended_p_square;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,105 @@
///////////////////////////////////////////////////////////////////////////////
// weighted_kurtosis.hpp
//
// Copyright 2006 Olivier Gygi, Daniel Egloff. 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_ACCUMULATORS_STATISTICS_WEIGHTED_KURTOSIS_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_KURTOSIS_HPP_EAN_28_10_2005
#include <limits>
#include <boost/mpl/placeholders.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/weighted_moment.hpp>
#include <boost/accumulators/statistics/weighted_mean.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// weighted_kurtosis_impl
/**
@brief Kurtosis estimation for weighted samples
The kurtosis of a sample distribution is defined as the ratio of the 4th central moment and the square of the 2nd central
moment (the variance) of the samples, minus 3. The term \f$ -3 \f$ is added in order to ensure that the normal distribution
has zero kurtosis. The kurtosis can also be expressed by the simple moments:
\f[
\hat{g}_2 =
\frac
{\widehat{m}_n^{(4)}-4\widehat{m}_n^{(3)}\hat{\mu}_n+6\widehat{m}_n^{(2)}\hat{\mu}_n^2-3\hat{\mu}_n^4}
{\left(\widehat{m}_n^{(2)} - \hat{\mu}_n^{2}\right)^2} - 3,
\f]
where \f$ \widehat{m}_n^{(i)} \f$ are the \f$ i \f$-th moment and \f$ \hat{\mu}_n \f$ the mean (first moment) of the
\f$ n \f$ samples.
The kurtosis estimator for weighted samples is formally identical to the estimator for unweighted samples, except that
the weighted counterparts of all measures it depends on are to be taken.
*/
template<typename Sample, typename Weight>
struct weighted_kurtosis_impl
: accumulator_base
{
typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
// for boost::result_of
typedef typename numeric::functional::fdiv<weighted_sample, weighted_sample>::result_type result_type;
weighted_kurtosis_impl(dont_care)
{
}
template<typename Args>
result_type result(Args const &args) const
{
return numeric::fdiv(
accumulators::weighted_moment<4>(args)
- 4. * accumulators::weighted_moment<3>(args) * weighted_mean(args)
+ 6. * accumulators::weighted_moment<2>(args) * weighted_mean(args) * weighted_mean(args)
- 3. * weighted_mean(args) * weighted_mean(args) * weighted_mean(args) * weighted_mean(args)
, ( accumulators::weighted_moment<2>(args) - weighted_mean(args) * weighted_mean(args) )
* ( accumulators::weighted_moment<2>(args) - weighted_mean(args) * weighted_mean(args) )
) - 3.;
}
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::weighted_kurtosis
//
namespace tag
{
struct weighted_kurtosis
: depends_on<weighted_mean, weighted_moment<2>, weighted_moment<3>, weighted_moment<4> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::weighted_kurtosis_impl<mpl::_1, mpl::_2> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::weighted_kurtosis
//
namespace extract
{
extractor<tag::weighted_kurtosis> const weighted_kurtosis = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_kurtosis)
}
using extract::weighted_kurtosis;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,196 @@
///////////////////////////////////////////////////////////////////////////////
// weighted_mean.hpp
//
// Copyright 2006 Eric Niebler, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_WEIGHTED_MEAN_HPP_EAN_03_11_2005
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_MEAN_HPP_EAN_03_11_2005
#include <boost/mpl/assert.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/weights.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/weighted_sum.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// weighted_mean_impl
// lazy, by default
template<typename Sample, typename Weight, typename Tag>
struct weighted_mean_impl
: accumulator_base
{
typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
// for boost::result_of
typedef typename numeric::functional::fdiv<weighted_sample, Weight>::result_type result_type;
weighted_mean_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
typedef
typename mpl::if_<
is_same<Tag, tag::sample>
, tag::weighted_sum
, tag::weighted_sum_of_variates<Sample, Tag>
>::type
weighted_sum_tag;
extractor<weighted_sum_tag> const some_weighted_sum = {};
return numeric::fdiv(some_weighted_sum(args), sum_of_weights(args));
}
};
///////////////////////////////////////////////////////////////////////////////
// immediate_weighted_mean_impl
// immediate
template<typename Sample, typename Weight, typename Tag>
struct immediate_weighted_mean_impl
: accumulator_base
{
typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
// for boost::result_of
typedef typename numeric::functional::fdiv<weighted_sample, Weight>::result_type result_type;
template<typename Args>
immediate_weighted_mean_impl(Args const &args)
: mean(
numeric::fdiv(
args[parameter::keyword<Tag>::get() | Sample()]
* numeric::one<Weight>::value
, numeric::one<Weight>::value
)
)
{
}
template<typename Args>
void operator ()(Args const &args)
{
// Matthias:
// need to pass the argument pack since the weight might be an external
// accumulator set passed as a named parameter
Weight w_sum = sum_of_weights(args);
Weight w = args[weight];
weighted_sample const &s = args[parameter::keyword<Tag>::get()] * w;
this->mean = numeric::fdiv(this->mean * (w_sum - w) + s, w_sum);
}
result_type result(dont_care) const
{
return this->mean;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int /* file_version */)
{
ar & mean;
}
private:
result_type mean;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::weighted_mean
// tag::immediate_weighted_mean
//
namespace tag
{
struct weighted_mean
: depends_on<sum_of_weights, weighted_sum>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::weighted_mean_impl<mpl::_1, mpl::_2, tag::sample> impl;
};
struct immediate_weighted_mean
: depends_on<sum_of_weights>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::immediate_weighted_mean_impl<mpl::_1, mpl::_2, tag::sample> impl;
};
template<typename VariateType, typename VariateTag>
struct weighted_mean_of_variates
: depends_on<sum_of_weights, weighted_sum_of_variates<VariateType, VariateTag> >
{
/// INTERNAL ONLY
///
typedef accumulators::impl::weighted_mean_impl<VariateType, mpl::_2, VariateTag> impl;
};
template<typename VariateType, typename VariateTag>
struct immediate_weighted_mean_of_variates
: depends_on<sum_of_weights>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::immediate_weighted_mean_impl<VariateType, mpl::_2, VariateTag> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::weighted_mean
// extract::weighted_mean_of_variates
//
namespace extract
{
extractor<tag::mean> const weighted_mean = {};
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, weighted_mean_of_variates, (typename)(typename))
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_mean)
}
using extract::weighted_mean;
using extract::weighted_mean_of_variates;
// weighted_mean(lazy) -> weighted_mean
template<>
struct as_feature<tag::weighted_mean(lazy)>
{
typedef tag::weighted_mean type;
};
// weighted_mean(immediate) -> immediate_weighted_mean
template<>
struct as_feature<tag::weighted_mean(immediate)>
{
typedef tag::immediate_weighted_mean type;
};
// weighted_mean_of_variates<VariateType, VariateTag>(lazy) -> weighted_mean_of_variates<VariateType, VariateTag>
template<typename VariateType, typename VariateTag>
struct as_feature<tag::weighted_mean_of_variates<VariateType, VariateTag>(lazy)>
{
typedef tag::weighted_mean_of_variates<VariateType, VariateTag> type;
};
// weighted_mean_of_variates<VariateType, VariateTag>(immediate) -> immediate_weighted_mean_of_variates<VariateType, VariateTag>
template<typename VariateType, typename VariateTag>
struct as_feature<tag::weighted_mean_of_variates<VariateType, VariateTag>(immediate)>
{
typedef tag::immediate_weighted_mean_of_variates<VariateType, VariateTag> type;
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,255 @@
///////////////////////////////////////////////////////////////////////////////
// weighted_median.hpp
//
// Copyright 2006 Eric Niebler, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_WEIGHTED_MEDIAN_HPP_EAN_28_10_2005
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_MEDIAN_HPP_EAN_28_10_2005
#include <boost/mpl/placeholders.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/median.hpp>
#include <boost/accumulators/statistics/weighted_p_square_quantile.hpp>
#include <boost/accumulators/statistics/weighted_density.hpp>
#include <boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// weighted_median_impl
//
/**
@brief Median estimation for weighted samples based on the \f$P^2\f$ quantile estimator
The \f$P^2\f$ algorithm for weighted samples is invoked with a quantile probability of 0.5.
*/
template<typename Sample>
struct weighted_median_impl
: accumulator_base
{
// for boost::result_of
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type result_type;
weighted_median_impl(dont_care) {}
template<typename Args>
result_type result(Args const &args) const
{
return weighted_p_square_quantile_for_median(args);
}
};
///////////////////////////////////////////////////////////////////////////////
// with_density_weighted_median_impl
//
/**
@brief Median estimation for weighted samples based on the density estimator
The algorithm determines the bin in which the \f$0.5*cnt\f$-th sample lies, \f$cnt\f$ being
the total number of samples. It returns the approximate horizontal position of this sample,
based on a linear interpolation inside the bin.
*/
template<typename Sample>
struct with_density_weighted_median_impl
: accumulator_base
{
typedef typename numeric::functional::fdiv<Sample, std::size_t>::result_type float_type;
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
typedef iterator_range<typename histogram_type::iterator> range_type;
// for boost::result_of
typedef float_type result_type;
template<typename Args>
with_density_weighted_median_impl(Args const &args)
: sum(numeric::fdiv(args[sample | Sample()], (std::size_t)1))
, is_dirty(true)
{
}
void operator ()(dont_care)
{
this->is_dirty = true;
}
template<typename Args>
result_type result(Args const &args) const
{
if (this->is_dirty)
{
this->is_dirty = false;
std::size_t cnt = count(args);
range_type histogram = weighted_density(args);
typename range_type::iterator it = histogram.begin();
while (this->sum < 0.5 * cnt)
{
this->sum += it->second * cnt;
++it;
}
--it;
float_type over = numeric::fdiv(this->sum - 0.5 * cnt, it->second * cnt);
this->median = it->first * over + (it + 1)->first * ( 1. - over );
}
return this->median;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & sum;
ar & is_dirty;
ar & median;
}
private:
mutable float_type sum;
mutable bool is_dirty;
mutable float_type median;
};
///////////////////////////////////////////////////////////////////////////////
// with_p_square_cumulative_distribution_weighted_median_impl
//
/**
@brief Median estimation for weighted samples based on the \f$P^2\f$ cumulative distribution estimator
The algorithm determines the first (leftmost) bin with a height exceeding 0.5. It
returns the approximate horizontal position of where the cumulative distribution
equals 0.5, based on a linear interpolation inside the bin.
*/
template<typename Sample, typename Weight>
struct with_p_square_cumulative_distribution_weighted_median_impl
: accumulator_base
{
typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
typedef typename numeric::functional::fdiv<weighted_sample, std::size_t>::result_type float_type;
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
typedef iterator_range<typename histogram_type::iterator> range_type;
// for boost::result_of
typedef float_type result_type;
with_p_square_cumulative_distribution_weighted_median_impl(dont_care)
: is_dirty(true)
{
}
void operator ()(dont_care)
{
this->is_dirty = true;
}
template<typename Args>
result_type result(Args const &args) const
{
if (this->is_dirty)
{
this->is_dirty = false;
range_type histogram = weighted_p_square_cumulative_distribution(args);
typename range_type::iterator it = histogram.begin();
while (it->second < 0.5)
{
++it;
}
float_type over = numeric::fdiv(it->second - 0.5, it->second - (it - 1)->second);
this->median = it->first * over + (it + 1)->first * ( 1. - over );
}
return this->median;
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & is_dirty;
ar & median;
}
private:
mutable bool is_dirty;
mutable float_type median;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::weighted_median
// tag::with_density_weighted_median
// tag::with_p_square_cumulative_distribution_weighted_median
//
namespace tag
{
struct weighted_median
: depends_on<weighted_p_square_quantile_for_median>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::weighted_median_impl<mpl::_1> impl;
};
struct with_density_weighted_median
: depends_on<count, weighted_density>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::with_density_weighted_median_impl<mpl::_1> impl;
};
struct with_p_square_cumulative_distribution_weighted_median
: depends_on<weighted_p_square_cumulative_distribution>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::with_p_square_cumulative_distribution_weighted_median_impl<mpl::_1, mpl::_2> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::weighted_median
//
namespace extract
{
extractor<tag::median> const weighted_median = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_median)
}
using extract::weighted_median;
// weighted_median(with_p_square_quantile) -> weighted_median
template<>
struct as_feature<tag::weighted_median(with_p_square_quantile)>
{
typedef tag::weighted_median type;
};
// weighted_median(with_density) -> with_density_weighted_median
template<>
struct as_feature<tag::weighted_median(with_density)>
{
typedef tag::with_density_weighted_median type;
};
// weighted_median(with_p_square_cumulative_distribution) -> with_p_square_cumulative_distribution_weighted_median
template<>
struct as_feature<tag::weighted_median(with_p_square_cumulative_distribution)>
{
typedef tag::with_p_square_cumulative_distribution_weighted_median type;
};
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,103 @@
///////////////////////////////////////////////////////////////////////////////
// weighted_moment.hpp
//
// Copyright 2006, Eric Niebler, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_WEIGHTED_MOMENT_HPP_EAN_15_11_2005
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_MOMENT_HPP_EAN_15_11_2005
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/framework/depends_on.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/moment.hpp> // for pow()
#include <boost/accumulators/statistics/sum.hpp>
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// weighted_moment_impl
template<typename N, typename Sample, typename Weight>
struct weighted_moment_impl
: accumulator_base // TODO: also depends_on sum of powers
{
BOOST_MPL_ASSERT_RELATION(N::value, >, 0);
typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
// for boost::result_of
typedef typename numeric::functional::fdiv<weighted_sample, Weight>::result_type result_type;
template<typename Args>
weighted_moment_impl(Args const &args)
: sum(args[sample | Sample()] * numeric::one<Weight>::value)
{
}
template<typename Args>
void operator ()(Args const &args)
{
this->sum += args[weight] * numeric::pow(args[sample], N());
}
template<typename Args>
result_type result(Args const &args) const
{
return numeric::fdiv(this->sum, sum_of_weights(args));
}
// make this accumulator serializeable
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & sum;
}
private:
weighted_sample sum;
};
} // namespace impl
///////////////////////////////////////////////////////////////////////////////
// tag::weighted_moment
//
namespace tag
{
template<int N>
struct weighted_moment
: depends_on<count, sum_of_weights>
{
/// INTERNAL ONLY
///
typedef accumulators::impl::weighted_moment_impl<mpl::int_<N>, mpl::_1, mpl::_2> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::weighted_moment
//
namespace extract
{
BOOST_ACCUMULATORS_DEFINE_EXTRACTOR(tag, weighted_moment, (int))
}
using extract::weighted_moment;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,275 @@
///////////////////////////////////////////////////////////////////////////////
// weighted_p_square_cumul_dist.hpp
//
// Copyright 2006 Daniel Egloff, Olivier Gygi. 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_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMUL_DIST_HPP_DE_01_01_2006
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMUL_DIST_HPP_DE_01_01_2006
#include <vector>
#include <functional>
#include <boost/parameter/keyword.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/range.hpp>
#include <boost/accumulators/framework/accumulator_base.hpp>
#include <boost/accumulators/framework/extractor.hpp>
#include <boost/accumulators/numeric/functional.hpp>
#include <boost/accumulators/framework/parameters/sample.hpp>
#include <boost/accumulators/statistics_fwd.hpp>
#include <boost/accumulators/statistics/count.hpp>
#include <boost/accumulators/statistics/sum.hpp>
#include <boost/accumulators/statistics/p_square_cumul_dist.hpp> // for named parameter p_square_cumulative_distribution_num_cells
namespace boost { namespace accumulators
{
namespace impl
{
///////////////////////////////////////////////////////////////////////////////
// weighted_p_square_cumulative_distribution_impl
// cumulative distribution calculation (as histogram)
/**
@brief Histogram calculation of the cumulative distribution with the \f$P^2\f$ algorithm for weighted samples
A histogram of the sample cumulative distribution is computed dynamically without storing samples
based on the \f$ P^2 \f$ algorithm for weighted samples. The returned histogram has a specifiable
amount (num_cells) equiprobable (and not equal-sized) cells.
Note that applying importance sampling results in regions to be more and other regions to be less
accurately estimated than without importance sampling, i.e., with unweighted samples.
For further details, see
R. Jain and I. Chlamtac, The P^2 algorithm for dynamic calculation of quantiles and
histograms without storing observations, Communications of the ACM,
Volume 28 (October), Number 10, 1985, p. 1076-1085.
@param p_square_cumulative_distribution_num_cells
*/
template<typename Sample, typename Weight>
struct weighted_p_square_cumulative_distribution_impl
: accumulator_base
{
typedef typename numeric::functional::multiplies<Sample, Weight>::result_type weighted_sample;
typedef typename numeric::functional::fdiv<weighted_sample, std::size_t>::result_type float_type;
typedef std::vector<std::pair<float_type, float_type> > histogram_type;
typedef std::vector<float_type> array_type;
// for boost::result_of
typedef iterator_range<typename histogram_type::iterator> result_type;
template<typename Args>
weighted_p_square_cumulative_distribution_impl(Args const &args)
: num_cells(args[p_square_cumulative_distribution_num_cells])
, heights(num_cells + 1)
, actual_positions(num_cells + 1)
, desired_positions(num_cells + 1)
, histogram(num_cells + 1)
, is_dirty(true)
{
}
template<typename Args>
void operator ()(Args const &args)
{
this->is_dirty = true;
std::size_t cnt = count(args);
std::size_t sample_cell = 1; // k
std::size_t b = this->num_cells;
// accumulate num_cells + 1 first samples
if (cnt <= b + 1)
{
this->heights[cnt - 1] = args[sample];
this->actual_positions[cnt - 1] = args[weight];
// complete the initialization of heights by sorting
if (cnt == b + 1)
{
//std::sort(this->heights.begin(), this->heights.end());
// TODO: we need to sort the initial samples (in heights) in ascending order and
// sort their weights (in actual_positions) the same way. The following lines do
// it, but there must be a better and more efficient way of doing this.
typename array_type::iterator it_begin, it_end, it_min;
it_begin = this->heights.begin();
it_end = this->heights.end();
std::size_t pos = 0;
while (it_begin != it_end)
{
it_min = std::min_element(it_begin, it_end);
std::size_t d = std::distance(it_begin, it_min);
std::swap(*it_begin, *it_min);
std::swap(this->actual_positions[pos], this->actual_positions[pos + d]);
++it_begin;
++pos;
}
// calculate correct initial actual positions
for (std::size_t i = 1; i < b; ++i)
{
this->actual_positions[i] += this->actual_positions[i - 1];
}
}
}
else
{
// find cell k such that heights[k-1] <= args[sample] < heights[k] and adjust extreme values
if (args[sample] < this->heights[0])
{
this->heights[0] = args[sample];
this->actual_positions[0] = args[weight];
sample_cell = 1;
}
else if (this->heights[b] <= args[sample])
{
this->heights[b] = args[sample];
sample_cell = b;
}
else
{
typename array_type::iterator it;
it = std::upper_bound(
this->heights.begin()
, this->heights.end()
, args[sample]
);
sample_cell = std::distance(this->heights.begin(), it);
}
// increment positions of markers above sample_cell
for (std::size_t i = sample_cell; i < b + 1; ++i)
{
this->actual_positions[i] += args[weight];
}
// determine desired marker positions
for (std::size_t i = 1; i < b + 1; ++i)
{
this->desired_positions[i] = this->actual_positions[0]
+ numeric::fdiv((i-1) * (sum_of_weights(args) - this->actual_positions[0]), b);
}
// adjust heights of markers 2 to num_cells if necessary
for (std::size_t i = 1; i < b; ++i)
{
// offset to desire position
float_type d = this->desired_positions[i] - this->actual_positions[i];
// offset to next position
float_type dp = this->actual_positions[i + 1] - this->actual_positions[i];
// offset to previous position
float_type dm = this->actual_positions[i - 1] - this->actual_positions[i];
// height ds
float_type hp = (this->heights[i + 1] - this->heights[i]) / dp;
float_type hm = (this->heights[i - 1] - this->heights[i]) / dm;
if ( ( d >= 1. && dp > 1. ) || ( d <= -1. && dm < -1. ) )
{
short sign_d = static_cast<short>(d / std::abs(d));
// try adjusting heights[i] using p-squared formula
float_type h = this->heights[i] + sign_d / (dp - dm) * ( (sign_d - dm) * hp + (dp - sign_d) * hm );
if ( this->heights[i - 1] < h && h < this->heights[i + 1] )
{
this->heights[i] = h;
}
else
{
// use linear formula
if (d>0)
{
this->heights[i] += hp;
}
if (d<0)
{
this->heights[i] -= hm;
}
}
this->actual_positions[i] += sign_d;
}
}
}
}
template<typename Args>
result_type result(Args const &args) const
{
if (this->is_dirty)
{
this->is_dirty = false;
// creates a vector of std::pair where each pair i holds
// the values heights[i] (x-axis of histogram) and
// actual_positions[i] / sum_of_weights (y-axis of histogram)
for (std::size_t i = 0; i < this->histogram.size(); ++i)
{
this->histogram[i] = std::make_pair(this->heights[i], numeric::fdiv(this->actual_positions[i], sum_of_weights(args)));
}
}
return make_iterator_range(this->histogram);
}
// make this accumulator serializeable
// TODO split to save/load and check on parameters provided in ctor
template<class Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & num_cells;
ar & heights;
ar & actual_positions;
ar & desired_positions;
ar & histogram;
ar & is_dirty;
}
private:
std::size_t num_cells; // number of cells b
array_type heights; // q_i
array_type actual_positions; // n_i
array_type desired_positions; // n'_i
mutable histogram_type histogram; // histogram
mutable bool is_dirty;
};
} // namespace detail
///////////////////////////////////////////////////////////////////////////////
// tag::weighted_p_square_cumulative_distribution
//
namespace tag
{
struct weighted_p_square_cumulative_distribution
: depends_on<count, sum_of_weights>
, p_square_cumulative_distribution_num_cells
{
typedef accumulators::impl::weighted_p_square_cumulative_distribution_impl<mpl::_1, mpl::_2> impl;
};
}
///////////////////////////////////////////////////////////////////////////////
// extract::weighted_p_square_cumulative_distribution
//
namespace extract
{
extractor<tag::weighted_p_square_cumulative_distribution> const weighted_p_square_cumulative_distribution = {};
BOOST_ACCUMULATORS_IGNORE_GLOBAL(weighted_p_square_cumulative_distribution)
}
using extract::weighted_p_square_cumulative_distribution;
}} // namespace boost::accumulators
#endif
@@ -0,0 +1,19 @@
///////////////////////////////////////////////////////////////////////////////
// weighted_p_square_cumulative_distribution.hpp
//
// Copyright 2012 Eric Niebler. 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_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
#define BOOST_ACCUMULATORS_STATISTICS_WEIGHTED_P_SQUARE_CUMULATIVE_DISTRIBUTION_HPP_03_19_2012
#if defined(_MSC_VER) || defined(__BORLANDC__) && !defined(__clang__) || defined(__DMC__)
# pragma message ("Warning: This header is deprecated. Please use: boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp")
#elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__) || defined(__BORLANDC__)
# warning "This header is deprecated. Please use: boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp"
#endif
#include <boost/accumulators/statistics/weighted_p_square_cumul_dist.hpp>
#endif

Some files were not shown because too many files have changed in this diff Show More