From 6f24a50fddc5aacf9da7c152ca75ed7183aeba91 Mon Sep 17 00:00:00 2001 From: Hans Dembinski Date: Sat, 16 Jul 2016 12:45:16 -0400 Subject: [PATCH] tabula rasa --- build/CMakeLists.txt | 120 +--- build/FindNumpy.cmake | 28 - build/FindROOT.cmake | 159 ----- build/FindSphinx.cmake | 13 - build/Jamfile.v2 | 21 - doc/Jamfile.jam | 27 - doc/changelog.qbk | 3 - doc/histogram.qbk | 38 - doc/html/BOOST_HISTOGRAM_AXIS_LIMIT.html | 49 -- doc/html/BOOST_HISTOGRAM_BASE_APPEND.html | 49 -- doc/html/BOOST_HISTOGRAM_BASE_CTOR.html | 49 -- doc/html/BOOST_HISTOGRAM_CTOR.html | 49 -- doc/html/BOOST_HISTOGRAM_FILL.html | 49 -- doc/html/BOOST_HISTOGRAM_VALUE.html | 49 -- doc/html/BOOST_HISTOGRAM_VARIANCE.html | 49 -- doc/html/BOOST_HISTOGRAM_WFILL.html | 49 -- doc/html/boost/histogram/axis_base.html | 100 --- doc/html/boost/histogram/basic_histogram.html | 140 ---- doc/html/boost/histogram/category_axis.html | 145 ---- doc/html/boost/histogram/histogram.html | 203 ------ doc/html/boost/histogram/integer_axis.html | 94 --- doc/html/boost/histogram/polar_axis.html | 123 ---- doc/html/boost/histogram/real_axis.html | 71 -- doc/html/boost/histogram/regular_axis.html | 133 ---- doc/html/boost/histogram/variable_axis.html | 134 ---- doc/html/boost/histogram/visitor/bins.html | 62 -- doc/html/boost/histogram/visitor/cmp.html | 66 -- doc/html/boost/histogram/visitor/index.html | 74 -- doc/html/boost/histogram/visitor/shape.html | 62 -- doc/html/boost/histogram/visitor/uoflow.html | 62 -- doc/html/boost_histogram/changelog.html | 40 -- doc/html/boost_histogram/introduction.html | 92 --- doc/html/boost_histogram/motivation.html | 64 -- doc/html/boost_histogram/notes.html | 526 -------------- doc/html/boost_histogram/rationale.html | 189 ----- doc/html/boost_histogram/references.html | 56 -- doc/html/boost_histogram/tutorial.html | 191 ----- doc/html/histogram/reference.html | 150 ---- doc/html/index.html | 115 --- doc/html/standalone_HTML.manifest | 31 - doc/index.qbk | 40 -- doc/intro.qbk | 28 - doc/motivation.qbk | 9 - doc/notes.qbk | 113 --- doc/rationale.qbk | 51 -- doc/references.qbk | 7 - doc/sphinx/conf.py.in | 54 -- doc/sphinx/types.rst | 54 -- doc/tutorial.qbk | 138 ---- include/boost/histogram.hpp | 1 - include/boost/histogram/axis.hpp | 82 ++- include/boost/histogram/basic_histogram.hpp | 142 ---- include/boost/histogram/histogram.hpp | 415 ++++------- include/boost/histogram/serialization.hpp | 164 ----- src/axis.cpp | 13 +- src/basic_histogram.cpp | 47 -- src/histogram.cpp | 29 - src/python/axis.cpp | 270 ------- src/python/basic_histogram.cpp | 53 -- src/python/histogram.cpp | 282 -------- src/python/module.cpp | 35 - src/python/serialization_suite.hpp | 117 ---- test/Jamfile.v2 | 30 - test/axis_test.cpp | 50 +- test/check/sizeof.cpp | 45 -- test/check/speed_cpp.cpp | 122 ++++ .../{speed_vs_root.cpp => speed_root.cpp} | 0 test/histogram_test.cpp | 381 +++++----- test/python_suite_test.py.in | 657 ------------------ test/serialization.cpp | 23 - 70 files changed, 545 insertions(+), 6631 deletions(-) delete mode 100644 build/FindNumpy.cmake delete mode 100644 build/FindROOT.cmake delete mode 100644 build/FindSphinx.cmake delete mode 100644 build/Jamfile.v2 delete mode 100644 doc/Jamfile.jam delete mode 100644 doc/changelog.qbk delete mode 100644 doc/histogram.qbk delete mode 100644 doc/html/BOOST_HISTOGRAM_AXIS_LIMIT.html delete mode 100644 doc/html/BOOST_HISTOGRAM_BASE_APPEND.html delete mode 100644 doc/html/BOOST_HISTOGRAM_BASE_CTOR.html delete mode 100644 doc/html/BOOST_HISTOGRAM_CTOR.html delete mode 100644 doc/html/BOOST_HISTOGRAM_FILL.html delete mode 100644 doc/html/BOOST_HISTOGRAM_VALUE.html delete mode 100644 doc/html/BOOST_HISTOGRAM_VARIANCE.html delete mode 100644 doc/html/BOOST_HISTOGRAM_WFILL.html delete mode 100644 doc/html/boost/histogram/axis_base.html delete mode 100644 doc/html/boost/histogram/basic_histogram.html delete mode 100644 doc/html/boost/histogram/category_axis.html delete mode 100644 doc/html/boost/histogram/histogram.html delete mode 100644 doc/html/boost/histogram/integer_axis.html delete mode 100644 doc/html/boost/histogram/polar_axis.html delete mode 100644 doc/html/boost/histogram/real_axis.html delete mode 100644 doc/html/boost/histogram/regular_axis.html delete mode 100644 doc/html/boost/histogram/variable_axis.html delete mode 100644 doc/html/boost/histogram/visitor/bins.html delete mode 100644 doc/html/boost/histogram/visitor/cmp.html delete mode 100644 doc/html/boost/histogram/visitor/index.html delete mode 100644 doc/html/boost/histogram/visitor/shape.html delete mode 100644 doc/html/boost/histogram/visitor/uoflow.html delete mode 100644 doc/html/boost_histogram/changelog.html delete mode 100644 doc/html/boost_histogram/introduction.html delete mode 100644 doc/html/boost_histogram/motivation.html delete mode 100644 doc/html/boost_histogram/notes.html delete mode 100644 doc/html/boost_histogram/rationale.html delete mode 100644 doc/html/boost_histogram/references.html delete mode 100644 doc/html/boost_histogram/tutorial.html delete mode 100644 doc/html/histogram/reference.html delete mode 100644 doc/html/index.html delete mode 100644 doc/html/standalone_HTML.manifest delete mode 100644 doc/index.qbk delete mode 100644 doc/intro.qbk delete mode 100644 doc/motivation.qbk delete mode 100644 doc/notes.qbk delete mode 100644 doc/rationale.qbk delete mode 100644 doc/references.qbk delete mode 100644 doc/sphinx/conf.py.in delete mode 100644 doc/sphinx/types.rst delete mode 100644 doc/tutorial.qbk delete mode 100644 include/boost/histogram/basic_histogram.hpp delete mode 100644 include/boost/histogram/serialization.hpp delete mode 100644 src/basic_histogram.cpp delete mode 100644 src/histogram.cpp delete mode 100644 src/python/axis.cpp delete mode 100644 src/python/basic_histogram.cpp delete mode 100644 src/python/histogram.cpp delete mode 100644 src/python/module.cpp delete mode 100644 src/python/serialization_suite.hpp delete mode 100644 test/Jamfile.v2 delete mode 100644 test/check/sizeof.cpp create mode 100644 test/check/speed_cpp.cpp rename test/check/{speed_vs_root.cpp => speed_root.cpp} (100%) delete mode 100755 test/python_suite_test.py.in delete mode 100644 test/serialization.cpp diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt index bedbcb79..a2fdf374 100644 --- a/build/CMakeLists.txt +++ b/build/CMakeLists.txt @@ -5,8 +5,6 @@ project(histogram) list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}) # setup build -option(USE_PYTHON "Build Python bindings" ON) -option(USE_NUMPY "Build Numpy support" ON) option(BUILD_CHECKS "Build auxillary checks" OFF) option(COVERAGE "Build with coverage instrumentation" OFF) @@ -14,7 +12,7 @@ if(${CMAKE_BUILD_TYPE}) STRING(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE) endif() -add_definitions(-Wall) +add_definitions(-Wall -std=c++11) add_definitions(-DBOOST_TEST_DYN_LINK) # for unit_test_framework find_package(Boost 1.55 REQUIRED @@ -22,58 +20,6 @@ find_package(Boost 1.55 REQUIRED set(LIBRARIES stdc++ m ${Boost_LIBRARIES}) -if(USE_PYTHON) - find_package(PythonInterp) - execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import sys; sys.stdout.write(sys.prefix)" - OUTPUT_VARIABLE PYTHON_ROOT) - set(_VERSION ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}) - string(REPLACE "." "" _VERSION_NO_DOTS ${_VERSION}) - find_library(PYTHON_LIBRARY - PATHS ${PYTHON_ROOT}/lib - NAMES - python${_VERSION_NO_DOTS} - python${_VERSION}mu - python${_VERSION}m - python${_VERSION}u - python${_VERSION} - ) - find_path(PYTHON_INCLUDE_DIR - NAMES Python.h - PATHS ${PYTHON_ROOT}/include - PATH_SUFFIXES - python${_VERSION}mu - python${_VERSION}m - python${_VERSION}u - python${_VERSION} - ) - message(STATUS "Python lib: ${PYTHON_LIBRARY}") - message(STATUS "Python include: ${PYTHON_INCLUDE_DIR}") - find_library(Boost_PYTHON_LIBRARY - NAMES - boost_python-py${_VERSION_NO_DOTS} - boost_python - PATHS ${Boost_LIBRARY_DIR} - NO_DEFAULT_PATHS - ) - message(STATUS "Found boost.python: ${Boost_PYTHON_LIBRARY}") - if(Boost_PYTHON_LIBRARY AND PYTHON_LIBRARY) - set(HAVE_PYTHON 1) - include_directories(${PYTHON_INCLUDE_DIR}) - - if(USE_NUMPY) - find_package(Numpy 1.7) - endif() - - if(NUMPY_FOUND) - set(HAVE_NUMPY 1) - include_directories(${NUMPY_INCLUDE_DIR}) - add_definitions(-DHAVE_NUMPY) - endif() - - set(LIBRARIES ${LIBRARIES} ${Boost_PYTHON_LIBRARY} ${PYTHON_LIBRARY}) - endif() -endif() - include_directories(../include ${Boost_INCLUDE_DIRS}) if(CMAKE_BUILD_TYPE STREQUAL "debug" OR COVERAGE) @@ -94,43 +40,16 @@ endif() # core library add_library(boost_histogram SHARED ../src/axis.cpp - ../src/basic_histogram.cpp - ../src/histogram.cpp ../src/nstore.cpp ../src/zero_suppression.cpp ) target_link_libraries(boost_histogram ${LIBRARIES}) -# python bindings -if(HAVE_PYTHON) - add_library(pyhistogram MODULE - ../src/python/module.cpp - ../src/python/axis.cpp - ../src/python/basic_histogram.cpp - ../src/python/histogram.cpp - ) - target_link_libraries(pyhistogram boost_histogram ${LIBRARIES}) - set_target_properties(pyhistogram PROPERTIES OUTPUT_NAME "histogram" PREFIX "" SUFFIX ".so") -endif() - # checks if(BUILD_CHECKS) - add_executable(sizeof - ../test/check/sizeof.cpp - ) - target_link_libraries(sizeof ${LIBRARIES}) - - find_package(ROOT) # only used in speed comparison - if(ROOT_FOUND) - add_executable(speed_vs_root - ../test/check/speed_vs_root.cpp) - target_include_directories(speed_vs_root PUBLIC ${ROOT_INCLUDE_DIR}) - target_link_libraries(speed_vs_root boost_histogram ${ROOT_LIBRARIES} ${LIBRARIES}) - endif() - if(HAVE_NUMPY) - # ugly hack to copy python script into build - configure_file(../test/check/speed_vs_numpy.py speed_vs_numpy.py COPY_ONLY) - endif() + add_executable(speed_cpp + ../test/check/speed_cpp.cpp) + target_link_libraries(speed_cpp boost_histogram ${LIBRARIES}) endif() # tests @@ -154,34 +73,3 @@ add_executable(nstore_test ../test/nstore_test.cpp) target_link_libraries(nstore_test boost_histogram ${LIBRARIES}) add_test(nstore_test nstore_test) - -if(HAVE_PYTHON) - configure_file(../test/python_suite_test.py.in python_suite_test.py) - add_test(python_suite_test python_suite_test.py) -endif() - -# doc -if(HAVE_PYTHON) - find_package(Sphinx) # optional - if(SPHINX_EXECUTABLE) - configure_file(${PROJECT_SOURCE_DIR}/../doc/sphinx/conf.py.in conf.py) - add_custom_target(html - ${SPHINX_EXECUTABLE} - -b html -d . -c . - ${PROJECT_SOURCE_DIR}/../doc/sphinx - ${PROJECT_SOURCE_DIR}/../doc/html - COMMENT "(Re)building HTML documentation with Sphinx") - add_dependencies(html pyhistogram) - endif() -endif() - -# install -install(DIRECTORY ../include/boost DESTINATION include) -install(TARGETS boost_histogram DESTINATION lib) -if (USE_PYTHON) - execute_process(COMMAND python -c "from distutils.sysconfig import get_python_lib; import sys; sys.stdout.write(get_python_lib())" - OUTPUT_VARIABLE PYTHON_MODULE_DIRS) - set(PYTHON_MODULE_DIRS "${PYTHON_MODULE_DIRS}:$ENV{PYTHONPATH}") - string(REPLACE ":" "\n " PYTHON_MODULE_DIRS ${PYTHON_MODULE_DIRS}) - install(CODE "message(\"= How-to install Python module =\\nCopy\\n histogram.so\\ninto one of these paths:\\n ${PYTHON_MODULE_DIRS}\")") -endif() diff --git a/build/FindNumpy.cmake b/build/FindNumpy.cmake deleted file mode 100644 index f26fa9fc..00000000 --- a/build/FindNumpy.cmake +++ /dev/null @@ -1,28 +0,0 @@ -# VARIABLES set by this module -# - NUMPY_INCLUDE_DIR -# - NUMPY_VERSION -# - NUMPY_FOUND -set(NUMPY_FOUND FALSE) - -execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c "import numpy, sys; sys.stdout.write(numpy.get_include())" - OUTPUT_VARIABLE NUMPY_INCLUDE_DIR) -execute_process( - COMMAND ${PYTHON_EXECUTABLE} -c "import numpy, sys; sys.stdout.write(numpy.version.version)" - OUTPUT_VARIABLE NUMPY_VERSION -) - -if(EXISTS ${NUMPY_INCLUDE_DIR}) - if(NOT NUMPY_FIND_QUIETLY) - message(STATUS "Numpy version: ${NUMPY_VERSION} (required >= ${Numpy_FIND_VERSION})") - endif() - if("${NUMPY_VERSION}" VERSION_GREATER "${Numpy_FIND_VERSION}") - set(NUMPY_FOUND TRUE) - else() - set(NUMPY_FOUND FALSE) - endif() -endif() - -if(NOT NUMPY_FOUND AND NUMPY_FIND_REQUIRED) - message (FATAL_ERROR "numpy missing") -endif() diff --git a/build/FindROOT.cmake b/build/FindROOT.cmake deleted file mode 100644 index c5fef351..00000000 --- a/build/FindROOT.cmake +++ /dev/null @@ -1,159 +0,0 @@ -# - Finds ROOT instalation -# This module sets up ROOT information -# It defines: -# ROOT_FOUND If the ROOT is found -# ROOT_INCLUDE_DIR PATH to the include directory -# ROOT_LIBRARIES Most common libraries -# ROOT_LIBRARY_DIR PATH to the library directory -# -# Updated by K. Smith (ksmith37@nd.edu) to properly handle -# dependncies in ROOT_GENERATE_DICTIONARY - -find_program(ROOT_CONFIG_EXECUTABLE root-config - PATHS $ENV{ROOTSYS}/bin) - -if(NOT ROOT_CONFIG_EXECUTABLE) - set(ROOT_FOUND FALSE) -else() - set(ROOT_FOUND TRUE) - - execute_process( - COMMAND ${ROOT_CONFIG_EXECUTABLE} --prefix - OUTPUT_VARIABLE ROOTSYS - OUTPUT_STRIP_TRAILING_WHITESPACE) - - execute_process( - COMMAND ${ROOT_CONFIG_EXECUTABLE} --version - OUTPUT_VARIABLE ROOT_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE) - - execute_process( - COMMAND ${ROOT_CONFIG_EXECUTABLE} --incdir - OUTPUT_VARIABLE ROOT_INCLUDE_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) - - execute_process( - COMMAND ${ROOT_CONFIG_EXECUTABLE} --libs - OUTPUT_VARIABLE ROOT_LIBRARIES - OUTPUT_STRIP_TRAILING_WHITESPACE) - - #set(ROOT_LIBRARIES ${ROOT_LIBRARIES} -lThread -lMinuit -lHtml -lVMC -lEG -lGeom -lTreePlayer -lXMLIO -lProof) - #set(ROOT_LIBRARIES ${ROOT_LIBRARIES} -lProofPlayer -lMLP -lSpectrum -lEve -lRGL -lGed -lXMLParser -lPhysics) - set(ROOT_LIBRARY_DIR ${ROOTSYS}/lib) -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(ROOT DEFAULT_MSG ROOT_CONFIG_EXECUTABLE - ROOTSYS ROOT_VERSION ROOT_INCLUDE_DIR ROOT_LIBRARIES ROOT_LIBRARY_DIR) - -mark_as_advanced(ROOT_CONFIG_EXECUTABLE) - -include(CMakeParseArguments) -find_program(ROOTCINT_EXECUTABLE rootcint PATHS $ENV{ROOTSYS}/bin) -find_program(GENREFLEX_EXECUTABLE genreflex PATHS $ENV{ROOTSYS}/bin) -find_package(GCCXML) - -#---------------------------------------------------------------------------- -# function ROOT_GENERATE_DICTIONARY( dictionary -# header1 header2 ... -# LINKDEF linkdef1 ... -# OPTIONS opt1...) -function(ROOT_GENERATE_DICTIONARY dictionary) - CMAKE_PARSE_ARGUMENTS(ARG "" "" "LINKDEF;OPTIONS" "" ${ARGN}) - #---Get the list of include directories------------------ - get_directory_property(incdirs INCLUDE_DIRECTORIES) - set(includedirs) - foreach( d ${incdirs}) - set(includedirs ${includedirs} -I${d}) - endforeach() - #---Get the list of header files------------------------- - set(headerfiles) - foreach(fp ${ARG_UNPARSED_ARGUMENTS}) - file(GLOB files ${fp}) - if(files) - foreach(f ${files}) - if(NOT f MATCHES LinkDef) - find_file(headerFile ${f} PATHS ${incdirs}) - set(headerfiles ${headerfiles} ${headerFile}) - unset(headerFile CACHE) - endif() - endforeach() - else() - find_file(headerFile ${fp} PATHS ${incdirs}) - set(headerfiles ${headerfiles} ${headerFile}) - unset(headerFile CACHE) - endif() - endforeach() - #---Get LinkDef.h file------------------------------------ - set(linkdefs) - foreach( f ${ARG_LINKDEF}) - find_file(linkFile ${f} PATHS ${incdirs}) - set(linkdefs ${linkdefs} ${linkFile}) - unset(linkFile CACHE) - endforeach() - #---call rootcint------------------------------------------ - add_custom_command(OUTPUT ${dictionary}.cxx ${dictionary}.h - COMMAND ${ROOTCINT_EXECUTABLE} -cint -f ${dictionary}.cxx - -c ${ARG_OPTIONS} ${includedirs} ${headerfiles} ${linkdefs} - DEPENDS ${headerfiles} ${linkdefs} VERBATIM) -endfunction() - -#---------------------------------------------------------------------------- -# function REFLEX_GENERATE_DICTIONARY(dictionary -# header1 header2 ... -# SELECTION selectionfile ... -# OPTIONS opt1...) -function(REFLEX_GENERATE_DICTIONARY dictionary) - CMAKE_PARSE_ARGUMENTS(ARG "" "" "SELECTION;OPTIONS" "" ${ARGN}) - #---Get the list of header files------------------------- - set(headerfiles) - foreach(fp ${ARG_UNPARSED_ARGUMENTS}) - file(GLOB files ${fp}) - if(files) - foreach(f ${files}) - set(headerfiles ${headerfiles} ${f}) - endforeach() - else() - set(headerfiles ${headerfiles} ${fp}) - endif() - endforeach() - #---Get Selection file------------------------------------ - if(IS_ABSOLUTE ${ARG_SELECTION}) - set(selectionfile ${ARG_SELECTION}) - else() - set(selectionfile ${CMAKE_CURRENT_SOURCE_DIR}/${ARG_SELECTION}) - endif() - #---Get the list of include directories------------------ - get_directory_property(incdirs INCLUDE_DIRECTORIES) - set(includedirs) - foreach( d ${incdirs}) - set(includedirs ${includedirs} -I${d}) - endforeach() - #---Get preprocessor definitions-------------------------- - get_directory_property(defs COMPILE_DEFINITIONS) - foreach( d ${defs}) - set(definitions ${definitions} -D${d}) - endforeach() - #---Nanes and others--------------------------------------- - set(gensrcdict ${dictionary}.cpp) - if(MSVC) - set(gccxmlopts "--gccxmlopt=\"--gccxml-compiler cl\"") - else() - #set(gccxmlopts "--gccxmlopt=\'--gccxml-cxxflags -m64 \'") - set(gccxmlopts) - endif() - #set(rootmapname ${dictionary}Dict.rootmap) - #set(rootmapopts --rootmap=${rootmapname} --rootmap-lib=${libprefix}${dictionary}Dict) - #---Check GCCXML and get path----------------------------- - if(GCCXML) - get_filename_component(gccxmlpath ${GCCXML} PATH) - else() - message(WARNING "GCCXML not found. Install and setup your environment to find 'gccxml' executable") - endif() - #---Actual command---------------------------------------- - add_custom_command(OUTPUT ${gensrcdict} ${rootmapname} - COMMAND ${GENREFLEX_EXECUTABLE} ${headerfiles} -o ${gensrcdict} ${gccxmlopts} ${rootmapopts} --select=${selectionfile} - --gccxmlpath=${gccxmlpath} ${ARG_OPTIONS} ${includedirs} ${definitions} - DEPENDS ${headerfiles} ${selectionfile}) -endfunction() - diff --git a/build/FindSphinx.cmake b/build/FindSphinx.cmake deleted file mode 100644 index a9e087f2..00000000 --- a/build/FindSphinx.cmake +++ /dev/null @@ -1,13 +0,0 @@ -find_program(SPHINX_EXECUTABLE NAMES sphinx-build - HINTS $ENV{SPHINX_DIR} - PATH_SUFFIXES bin - DOC "Sphinx documentation generator" -) - -include(FindPackageHandleStandardArgs) - -find_package_handle_standard_args(Sphinx DEFAULT_MSG - SPHINX_EXECUTABLE -) - -mark_as_advanced(SPHINX_EXECUTABLE) diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 deleted file mode 100644 index 9780fdec..00000000 --- a/build/Jamfile.v2 +++ /dev/null @@ -1,21 +0,0 @@ -# (C) Copyright 2016 Klemens D. Morgenstern -# 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.) - -project /boost/histogram : source-location ../src ; - -lib boost_histogram : axis.cpp basic_histogram.cpp histogram.cpp nstore.cpp zero_suppression.cpp ; - -import python ; - -python-extension histogram : - python/axis.cpp - python/basic_histogram.cpp - python/histogram.cpp - python/module.cpp - /boost//serialization - /boost//python - boost_histogram - : release shared ; - -boost-install boost_histogram histogram ; diff --git a/doc/Jamfile.jam b/doc/Jamfile.jam deleted file mode 100644 index 63591f5e..00000000 --- a/doc/Jamfile.jam +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2016 Klemens D. Morgenstern -# -# 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) - -using boostbook ; -using quickbook ; -using doxygen ; - -doxygen autodoc -: - ../../../boost/histogram.hpp - [ glob ../../../boost/histogram/*.hpp ] -: - PREDEFINED=BOOST_HISTOGRAM_DOXYGEN - HIDE_UNDOC_CLASSES=YES - HIDE_UNDOC_MEMBERS=YES -; - -boostbook standalone -: - histogram.qbk -: - autodoc - boost.root=../../../.. - html.stylesheet=../../../../doc/src/boostbook.css -; diff --git a/doc/changelog.qbk b/doc/changelog.qbk deleted file mode 100644 index 73c3eea8..00000000 --- a/doc/changelog.qbk +++ /dev/null @@ -1,3 +0,0 @@ -[section Changelog] - -[endsect] \ No newline at end of file diff --git a/doc/histogram.qbk b/doc/histogram.qbk deleted file mode 100644 index 73b6b2c8..00000000 --- a/doc/histogram.qbk +++ /dev/null @@ -1,38 +0,0 @@ -[library Boost.Histogram - [quickbook 1.5] - [authors [Dembinski, Hans]] - [copyright 2016 Hand Dembinski] - [id histogram] - [dirname histogram] - [license - 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) - ] -] - - -[section:descr Description] - -This project contains an easy-to-use powerful n-dimensional histogram class implemented in C++03, -optimized for convenience and excellent performance under heavy duty. -Move semantics are supported using `boost::move`. -The histogram has a complete C++ and a [@http://www.python.org Python] interface, -and can be passed over the language boundary with ease. [@http://www.numpy.org Numpy] -is fully supported; histograms can be filled with Numpy arrays at C speeds and -are convertible into Numpy arrays without copying data. Histograms can be streamed -from/to files and pickled in Python. - -My goal is to submit this project to the [@http://www.boost.org Boost Libraries] - -[endsect] - -[include motivation.qbk] -[include intro.qbk] -[include tutorial.qbk] -[include notes.qbk] -[include rationale.qbk] -[include references.qbk] - -[xinclude autodoc.xml] -[include changelog.qbk] diff --git a/doc/html/BOOST_HISTOGRAM_AXIS_LIMIT.html b/doc/html/BOOST_HISTOGRAM_AXIS_LIMIT.html deleted file mode 100644 index cec754c3..00000000 --- a/doc/html/BOOST_HISTOGRAM_AXIS_LIMIT.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Macro BOOST_HISTOGRAM_AXIS_LIMIT - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Macro BOOST_HISTOGRAM_AXIS_LIMIT

-

BOOST_HISTOGRAM_AXIS_LIMIT

-
-

Synopsis

-
// In header: <boost/histogram/basic_histogram.hpp>
-
-BOOST_HISTOGRAM_AXIS_LIMIT
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/BOOST_HISTOGRAM_BASE_APPEND.html b/doc/html/BOOST_HISTOGRAM_BASE_APPEND.html deleted file mode 100644 index 17fda64f..00000000 --- a/doc/html/BOOST_HISTOGRAM_BASE_APPEND.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Macro BOOST_HISTOGRAM_BASE_APPEND - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Macro BOOST_HISTOGRAM_BASE_APPEND

-

BOOST_HISTOGRAM_BASE_APPEND

-
-

Synopsis

-
// In header: <boost/histogram/basic_histogram.hpp>
-
-BOOST_HISTOGRAM_BASE_APPEND(z, n, unused)
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/BOOST_HISTOGRAM_BASE_CTOR.html b/doc/html/BOOST_HISTOGRAM_BASE_CTOR.html deleted file mode 100644 index e9b396e3..00000000 --- a/doc/html/BOOST_HISTOGRAM_BASE_CTOR.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Macro BOOST_HISTOGRAM_BASE_CTOR - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Macro BOOST_HISTOGRAM_BASE_CTOR

-

BOOST_HISTOGRAM_BASE_CTOR

-
-

Synopsis

-
// In header: <boost/histogram/basic_histogram.hpp>
-
-BOOST_HISTOGRAM_BASE_CTOR(z, n, unused)
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/BOOST_HISTOGRAM_CTOR.html b/doc/html/BOOST_HISTOGRAM_CTOR.html deleted file mode 100644 index 3a611b97..00000000 --- a/doc/html/BOOST_HISTOGRAM_CTOR.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Macro BOOST_HISTOGRAM_CTOR - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Macro BOOST_HISTOGRAM_CTOR

-

BOOST_HISTOGRAM_CTOR

-
-

Synopsis

-
// In header: <boost/histogram/histogram.hpp>
-
-BOOST_HISTOGRAM_CTOR(z, n, unused)
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/BOOST_HISTOGRAM_FILL.html b/doc/html/BOOST_HISTOGRAM_FILL.html deleted file mode 100644 index 056de96d..00000000 --- a/doc/html/BOOST_HISTOGRAM_FILL.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Macro BOOST_HISTOGRAM_FILL - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Macro BOOST_HISTOGRAM_FILL

-

BOOST_HISTOGRAM_FILL

-
-

Synopsis

-
// In header: <boost/histogram/histogram.hpp>
-
-BOOST_HISTOGRAM_FILL(z, n, unused)
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/BOOST_HISTOGRAM_VALUE.html b/doc/html/BOOST_HISTOGRAM_VALUE.html deleted file mode 100644 index 2c9ea24a..00000000 --- a/doc/html/BOOST_HISTOGRAM_VALUE.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Macro BOOST_HISTOGRAM_VALUE - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Macro BOOST_HISTOGRAM_VALUE

-

BOOST_HISTOGRAM_VALUE

-
-

Synopsis

-
// In header: <boost/histogram/histogram.hpp>
-
-BOOST_HISTOGRAM_VALUE(z, n, unused)
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/BOOST_HISTOGRAM_VARIANCE.html b/doc/html/BOOST_HISTOGRAM_VARIANCE.html deleted file mode 100644 index 34a2f84f..00000000 --- a/doc/html/BOOST_HISTOGRAM_VARIANCE.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Macro BOOST_HISTOGRAM_VARIANCE - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Macro BOOST_HISTOGRAM_VARIANCE

-

BOOST_HISTOGRAM_VARIANCE

-
-

Synopsis

-
// In header: <boost/histogram/histogram.hpp>
-
-BOOST_HISTOGRAM_VARIANCE(z, n, unused)
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/BOOST_HISTOGRAM_WFILL.html b/doc/html/BOOST_HISTOGRAM_WFILL.html deleted file mode 100644 index 4eaf9f2e..00000000 --- a/doc/html/BOOST_HISTOGRAM_WFILL.html +++ /dev/null @@ -1,49 +0,0 @@ - - - -Macro BOOST_HISTOGRAM_WFILL - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Macro BOOST_HISTOGRAM_WFILL

-

BOOST_HISTOGRAM_WFILL

-
-

Synopsis

-
// In header: <boost/histogram/histogram.hpp>
-
-BOOST_HISTOGRAM_WFILL(z, n, unused)
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/axis_base.html b/doc/html/boost/histogram/axis_base.html deleted file mode 100644 index fc4fe752..00000000 --- a/doc/html/boost/histogram/axis_base.html +++ /dev/null @@ -1,100 +0,0 @@ - - - -Class axis_base - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Class axis_base

-

boost::histogram::axis_base — common base class for most axes

-
-

Synopsis

-
// In header: <boost/histogram/axis.hpp>
-
-
-class axis_base {
-public:
-  // construct/copy/destruct
-  axis_base(int, const std::string &, bool);
-  axis_base();
-  axis_base(const axis_base &);
-  axis_base & operator=(const axis_base &);
-
-  // public member functions
-  int bins() const;
-  bool uoflow() const;
-  const std::string & label() const;
-  void label(const std::string &);
-
-  // protected member functions
-  bool operator==(const axis_base &) const;
-};
-
-

Description

-
-

-axis_base - public - construct/copy/destruct

-
    -
  1. axis_base(int, const std::string &, bool);
  2. -
  3. axis_base();
  4. -
  5. axis_base(const axis_base &);
  6. -
  7. axis_base & operator=(const axis_base &);
  8. -
-
-
-

-axis_base public member functions

-
    -
  1. -
    int bins() const;
    Returns the number of bins.
  2. -
  3. -
    bool uoflow() const;
    Returns whether overflow and underflow bins will be added in the histogram.
  4. -
  5. -
    const std::string & label() const;
    Change the label of an axis (not implemented for category_axis).
  6. -
  7. -
    void label(const std::string & label);
    Returns the axis label, which is a name or description (not implemented for category_axis).
  8. -
-
-
-

-axis_base protected member functions

-
  1. bool operator==(const axis_base &) const;
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/basic_histogram.html b/doc/html/boost/histogram/basic_histogram.html deleted file mode 100644 index 0e18ae5d..00000000 --- a/doc/html/boost/histogram/basic_histogram.html +++ /dev/null @@ -1,140 +0,0 @@ - - - -Class basic_histogram - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Class basic_histogram

-

boost::histogram::basic_histogram — This class holds collection of axis instances and computes the internal index.

-
-

Synopsis

-
// In header: <boost/histogram/basic_histogram.hpp>
-
-
-class basic_histogram {
-public:
-  // types
-  typedef container::vector< axis_type > axes_type;
-  typedef uintptr_t                      size_type;
-
-  // construct/copy/destruct
-  basic_histogram(const basic_histogram &);
-  basic_histogram(BOOST_RV_REF(basic_histogram));
-  explicit basic_histogram(const axes_type &);
-  basic_histogram & operator=(BOOST_COPY_ASSIGN_REF(basic_histogram));
-  basic_histogram & operator=(BOOST_RV_REF(basic_histogram));
-  ~basic_histogram();
-
-  // public member functions
-  unsigned dim() const;
-  int bins(unsigned) const;
-  unsigned shape(unsigned) const;
-  template<typename T> 
-    enable_if< is_same< T, axis_type >, T & >::type axis(unsigned);
-  template<typename T> 
-    disable_if< is_same< T, axis_type >, T & >::type axis(unsigned);
-  template<typename T> 
-    enable_if< is_same< T, axis_type >, const T & >::type axis(unsigned) const;
-  template<typename T> 
-    disable_if< is_same< T, axis_type >, const T & >::type 
-    axis(unsigned) const;
-  template<typename T> T & axis(unsigned);
-  template<typename T> const T & axis(unsigned) const;
-  bool operator==(const basic_histogram &) const;
-  template<typename Iterator> 
-    size_type pos(const Iterator &, const Iterator &) const;
-  template<typename Iterator> 
-    size_type linearize(const Iterator &, const Iterator &) const;
-  size_type field_count() const;
-};
-
-

Description

-
-

-basic_histogram - public - construct/copy/destruct

-
    -
  1. basic_histogram(const basic_histogram & o);
  2. -
  3. basic_histogram(BOOST_RV_REF(basic_histogram) o);
  4. -
  5. explicit basic_histogram(const axes_type & axes);
  6. -
  7. basic_histogram & operator=(BOOST_COPY_ASSIGN_REF(basic_histogram) o);
  8. -
  9. basic_histogram & operator=(BOOST_RV_REF(basic_histogram) o);
  10. -
  11. ~basic_histogram();
  12. -
-
-
-

-basic_histogram public member functions

-
    -
  1. -
    unsigned dim() const;
    Returns the number of dimensions of the histogram, how many axis it has.
  2. -
  3. -
    int bins(unsigned i) const;
    Returns the number of bins for axis i.
  4. -
  5. -
    unsigned shape(unsigned i) const;
    -

    Returns the actual number of fields used by the axis. If the axis has no underflow and overflow bins, this is equal to bins. Otherwise, the number is larger by 2.

    -
  6. -
  7. template<typename T> 
    -  enable_if< is_same< T, axis_type >, T & >::type axis(unsigned i);
  8. -
  9. template<typename T> 
    -  disable_if< is_same< T, axis_type >, T & >::type axis(unsigned i);
  10. -
  11. template<typename T> 
    -  enable_if< is_same< T, axis_type >, const T & >::type axis(unsigned i) const;
  12. -
  13. template<typename T> 
    -  disable_if< is_same< T, axis_type >, const T & >::type 
    -  axis(unsigned i) const;
  14. -
  15. -
    template<typename T> T & axis(unsigned i);
    -

    Returns the axis object at index i, casted to type T. A runtime exception is thrown if the type cast is invalid.

    -
  16. -
  17. -
    template<typename T> const T & axis(unsigned i) const;
    -

    The const-version of the previous member function.

    -
  18. -
  19. bool operator==(const basic_histogram &) const;
  20. -
  21. template<typename Iterator> 
    -  size_type pos(const Iterator & begin, const Iterator & end) const;
  22. -
  23. template<typename Iterator> 
    -  size_type linearize(const Iterator & begin, const Iterator & end) const;
  24. -
  25. -
    size_type field_count() const;
    Returns the number of fields needed for storage.
  26. -
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/category_axis.html b/doc/html/boost/histogram/category_axis.html deleted file mode 100644 index 5a496fab..00000000 --- a/doc/html/boost/histogram/category_axis.html +++ /dev/null @@ -1,145 +0,0 @@ - - - -Class category_axis - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Class category_axis

-

boost::histogram::category_axis — An axis for enumerated categories. The axis stores the category labels, and expects that they are addressed using an integer from 0 to n-1. There are no underflow/overflow bins for this axis. Binning is a O(1) operation.

-
-

Synopsis

-
// In header: <boost/histogram/axis.hpp>
-
-
-class category_axis {
-public:
-  // types
-  typedef std::string value_type;
-
-  // construct/copy/destruct
-  explicit category_axis(const std::string &);
-  explicit category_axis(const std::vector< std::string > &);
-  category_axis();
-  category_axis(const category_axis &);
-  category_axis & operator=(const category_axis &);
-
-  // public member functions
-  int bins() const;
-  int index(double) const;
-  const std::string & operator[](int) const;
-  bool uoflow() const;
-  bool operator==(const category_axis &) const;
-};
-
-

Description

-
-

-category_axis - public - construct/copy/destruct

-
    -
  1. -
    explicit category_axis(const std::string & categories);
    -

    Construct from a single string

    -

    -

    -
    ---- - - - - -

    Parameters:

    ---- - - - - -

    categories

    a string of categories separated by the character ;

    -
  2. -
  3. -
    explicit category_axis(const std::vector< std::string > & categories);
    -

    Construct from a single string

    -

    -

    -
    ---- - - - - -

    Parameters:

    ---- - - - - -

    categories

    an ordered sequence of categories that this axis discriminates

    -
  4. -
  5. category_axis();
  6. -
  7. category_axis(const category_axis &);
  8. -
  9. category_axis & operator=(const category_axis &);
  10. -
-
-
-

-category_axis public member functions

-
    -
  1. int bins() const;
  2. -
  3. -
    int index(double x) const;
    Returns the bin index for the passed argument.
  4. -
  5. -
    const std::string & operator[](int idx) const;
    Returns the category for the bin index.
  6. -
  7. bool uoflow() const;
  8. -
  9. bool operator==(const category_axis &) const;
  10. -
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/histogram.html b/doc/html/boost/histogram/histogram.html deleted file mode 100644 index 7c13d5bc..00000000 --- a/doc/html/boost/histogram/histogram.html +++ /dev/null @@ -1,203 +0,0 @@ - - - -Class histogram - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Class histogram

-

boost::histogram::histogram

-
-

Synopsis

-
// In header: <boost/histogram/histogram.hpp>
-
-
-class histogram : public boost::histogram::basic_histogram {
-public:
-  // construct/copy/destruct
-  histogram();
-  explicit histogram(const axes_type &);
-  explicit histogram(const axis_type &, ...);
-  histogram(const histogram &);
-  histogram(BOOST_RV_REF(histogram));
-  histogram & operator=(BOOST_COPY_ASSIGN_REF(histogram));
-  histogram & operator=(BOOST_RV_REF(histogram));
-
-  // public member functions
-  template<typename Iterator> 
-    boost::disable_if< boost::is_arithmetic< Iterator >, void >::type 
-    fill(Iterator, Iterator);
-  void fill(double, ...);
-  template<typename Iterator> 
-    boost::disable_if< boost::is_arithmetic< Iterator >, void >::type 
-    wfill(Iterator, Iterator, double);
-  void fill(double, ...);
-  template<typename Iterator> 
-    boost::disable_if< boost::is_arithmetic< Iterator >, double >::type 
-    value(Iterator, Iterator) const;
-  void value(double, ...);
-  template<typename Iterator> 
-    boost::disable_if< boost::is_arithmetic< Iterator >, double >::type 
-    variance(Iterator, Iterator) const;
-  void variance(double, ...);
-  unsigned depth() const;
-  double sum() const;
-  bool operator==(const histogram &) const;
-  histogram & operator+=(const histogram &);
-  const void * buffer() const;
-};
-
-

Description

-

The class implements an n-dimensional histogram, managing counts in bins.

-

It inherits from basic_histogram, which manages the stored axis instances and the conversion of an n-dimensional tuple or index into an internal linear offset that is used to address the bin count. How the bin count is stored is an encapsulated implementation detail.

-
-

-histogram - public - construct/copy/destruct

-
    -
  1. histogram();
  2. -
  3. explicit histogram(const axes_type & axes);
  4. -
  5. -
    explicit histogram(const axis_type & a0, ...);
    -

    Constructors for a variable number of axis types, each defining the binning scheme for its dimension. Up to BOOST_HISTOGRAM_AXIS_LIMIT axis types can be passed to the constructor, yielding the same number of dimensions.

    -
  6. -
  7. histogram(const histogram & o);
  8. -
  9. histogram(BOOST_RV_REF(histogram) o);
  10. -
  11. histogram & operator=(BOOST_COPY_ASSIGN_REF(histogram) o);
  12. -
  13. histogram & operator=(BOOST_RV_REF(histogram) o);
  14. -
-
-
-

-histogram public member functions

-
    -
  1. -
    template<typename Iterator> 
    -  boost::disable_if< boost::is_arithmetic< Iterator >, void >::type 
    -  fill(Iterator begin, Iterator end);
    -

    Fills the histogram with a range. It checks at run-time that the size agrees with the dimensions of the histogram.

    -

    Allocation of internal memory is delayed until the first call to this function.

    -

    -

    -
    ---- - - - - -

    Throws:

    std::range_error If the range doesn't fit the dimension of the histogram.
    -
  2. -
  3. void fill(double x0, ...);
  4. -
  5. -
    template<typename Iterator> 
    -  boost::disable_if< boost::is_arithmetic< Iterator >, void >::type 
    -  wfill(Iterator begin, Iterator end, double w);
    -

    Fills the histogram from a iterator range, using a weight. It checks at run-time that the length agrees with the dimensions of the histogram.

    -

    Allocation of internal memory is delayed until the first call to this function. If the histogram was filled with :cpp:func:fill_c before, the internal memory is converted to the wide format used for storing weighted counts.

    -

    If the data is not weighted (all weights are 1.0), using fill is much more space-efficient. In the most extreme case, storing of weighted counts consumes 16x more memory.

    -

    -This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

    -

    Overload taking a variadic sequence.

    -
    ---- - - - - -

    Throws:

    std::range_error If the range doesn't fit the dimension of the histogram.
    -
  6. -
  7. void fill(double x0, ...);
  8. -
  9. -
    template<typename Iterator> 
    -  boost::disable_if< boost::is_arithmetic< Iterator >, double >::type 
    -  value(Iterator begin, Iterator end) const;
    -

    Returns the count of the bin addressed by the supplied index. Just like in Python, negative indices like -1 are allowed and count from the end. So if an axis has k bins, -1 points to k-1.

    -

    -

    -
    ---- - - - - -

    Throws:

    std::range_error if the length does not match the dimension
    -
  10. -
  11. void value(double x0, ...);
  12. -
  13. -
    template<typename Iterator> 
    -  boost::disable_if< boost::is_arithmetic< Iterator >, double >::type 
    -  variance(Iterator begin, Iterator end) const;
    -

    Returns the variance estimate for the count of the bin addressed by the supplied index. Negative indices are allowed just like in case of histogram::value

    -

    Note that it does not return the standard deviation :math:\sigma, commonly called "error", but the variance .

    -

    In case of unweighted counts, the variance estimate returned is , if the count is . This is a common estimate for the variance based on the theory of the Poisson distribution. In case of weighted counts, the variance estimate returned is , if the individual weights are . This estimate can be derived from the estimate above using uncertainty propagation. The extra storage needed for keeping track of the this sum is the reason why a histogram with weighted counts consumes more memory.

    -

    -

    -
    ---- - - - - -

    Throws:

    std::range_error if the length does not match the dimension
    -
  14. -
  15. void variance(double x0, ...);
  16. -
  17. -
    unsigned depth() const;
    Returns the current size of a count in the internal memory buffer in number of bytes.
  18. -
  19. -
    double sum() const;
    Returns the sum of bin counts, including overflow and underflow bins. This could be implemented as a free function.
  20. -
  21. -
    bool operator==(const histogram & o) const;
    Returns true if the two histograms have the dimension, same axis types, and same data content. Two otherwise identical histograms are not considered equal, if they do not have the same depth, even if counts and variances are the same. This case only occurs if one histogram is filled using :cpp:func:fill and the other with :cpp:func:wfill, using weights of 1.
  22. -
  23. -
    histogram & operator+=(const histogram & o);
    Adds the counts of the histogram on the right hand side to this histogram, if the two histograms have the same signature. Otherwise, a :cpp:type:std::logic_error is thrown. Returns itself.
  24. -
  25. const void * buffer() const;
  26. -
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/integer_axis.html b/doc/html/boost/histogram/integer_axis.html deleted file mode 100644 index 3aa16ccf..00000000 --- a/doc/html/boost/histogram/integer_axis.html +++ /dev/null @@ -1,94 +0,0 @@ - - - -Class integer_axis - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Class integer_axis

-

boost::histogram::integer_axis

-
-

Synopsis

-
// In header: <boost/histogram/axis.hpp>
-
-
-class integer_axis : public boost::histogram::axis_base {
-public:
-  // types
-  typedef int value_type;
-
-  // construct/copy/destruct
-  integer_axis(int, int, const std::string & = std::string(), bool = true);
-  integer_axis();
-  integer_axis(const integer_axis &);
-  integer_axis & operator=(const integer_axis &);
-
-  // public member functions
-  int index(double) const;
-  int operator[](int) const;
-  bool operator==(const integer_axis &) const;
-};
-
-

Description

-

An axis for a contiguous range of integers. There are no underflow/overflow bins for this axis. Binning is a O(1) operation.

-
-

-integer_axis - public - construct/copy/destruct

-
    -
  1. -
    integer_axis(int min, int max, const std::string & label = std::string(), 
    -             bool uoflow = true);
    Constructor.
  2. -
  3. integer_axis();
  4. -
  5. integer_axis(const integer_axis &);
  6. -
  7. integer_axis & operator=(const integer_axis &);
  8. -
-
-
-

-integer_axis public member functions

-
    -
  1. -
    int index(double x) const;
    Returns the bin index for the passed argument.
  2. -
  3. -
    int operator[](int idx) const;
    Returns the integer that is mapped to the bin index.
  4. -
  5. bool operator==(const integer_axis &) const;
  6. -
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/polar_axis.html b/doc/html/boost/histogram/polar_axis.html deleted file mode 100644 index 6bad57d1..00000000 --- a/doc/html/boost/histogram/polar_axis.html +++ /dev/null @@ -1,123 +0,0 @@ - - - -Class polar_axis - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Class polar_axis

-

boost::histogram::polar_axis — An axis for real-valued angles. There are no overflow/underflow bins for this axis, since the axis is circular and wraps around after :math:2 \pi. Binning is a O(1) operation.

-
-

Synopsis

-
// In header: <boost/histogram/axis.hpp>
-
-
-class polar_axis : public boost::histogram::axis_base,
-                   public boost::histogram::real_axis< polar_axis >
-{
-public:
-  // construct/copy/destruct
-  explicit polar_axis(int, double = 0.0, const std::string & = std::string());
-  polar_axis();
-  polar_axis(const polar_axis &);
-  polar_axis & operator=(const polar_axis &);
-
-  // public member functions
-  int index(double) const;
-  double operator[](int) const;
-  bool operator==(const polar_axis &) const;
-};
-
-

Description

-
-

-polar_axis - public - construct/copy/destruct

-
    -
  1. -
    explicit polar_axis(int n, double start = 0.0, 
    -                    const std::string & label = std::string());
    -

    Constructor -

    -
    ---- - - - - -

    Parameters:

    ---- - - - - - - - - - - - - - - -

    label

    description of the axis

    n

    number of bins

    start

    starting phase of the angle

    -
  2. -
  3. polar_axis();
  4. -
  5. polar_axis(const polar_axis &);
  6. -
  7. polar_axis & operator=(const polar_axis &);
  8. -
-
-
-

-polar_axis public member functions

-
    -
  1. -
    int index(double x) const;
    Returns the bin index for the passed argument.
  2. -
  3. double operator[](int idx) const;
  4. -
  5. bool operator==(const polar_axis &) const;
  6. -
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/real_axis.html b/doc/html/boost/histogram/real_axis.html deleted file mode 100644 index 5fa2ea02..00000000 --- a/doc/html/boost/histogram/real_axis.html +++ /dev/null @@ -1,71 +0,0 @@ - - - -Class template real_axis - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Class template real_axis

-

boost::histogram::real_axis

-
-

Synopsis

-
// In header: <boost/histogram/axis.hpp>
-
-template<typename Derived> 
-class real_axis {
-public:
-  // types
-  typedef double value_type;
-
-  // public member functions
-  double left(int) const;
-  double right(int) const;
-  double center(int) const;
-};
-
-

Description

-
-

-real_axis public member functions

-
    -
  1. double left(int idx) const;
  2. -
  3. double right(int idx) const;
  4. -
  5. double center(int idx) const;
  6. -
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/regular_axis.html b/doc/html/boost/histogram/regular_axis.html deleted file mode 100644 index f04e46b8..00000000 --- a/doc/html/boost/histogram/regular_axis.html +++ /dev/null @@ -1,133 +0,0 @@ - - - -Class regular_axis - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Class regular_axis

-

boost::histogram::regular_axis — An axis for real-valued data and bins of equal width. Binning is a O(1) operation.

-
-

Synopsis

-
// In header: <boost/histogram/axis.hpp>
-
-
-class regular_axis : public boost::histogram::axis_base,
-                     public boost::histogram::real_axis< regular_axis >
-{
-public:
-  // construct/copy/destruct
-  regular_axis(int, double, double, const std::string & = std::string(), 
-               bool = true);
-  regular_axis();
-  regular_axis(const regular_axis &);
-  regular_axis & operator=(const regular_axis &);
-
-  // public member functions
-  int index(double) const;
-  double operator[](int) const;
-  bool operator==(const regular_axis &) const;
-};
-
-

Description

-
-

-regular_axis - public - construct/copy/destruct

-
    -
  1. -
    regular_axis(int n, double min, double max, 
    -             const std::string & label = std::string(), bool uoflow = true);
    -

    Constructor

    -

    -

    -
    ---- - - - - -

    Parameters:

    ---- - - - - - - - - - - - - - - - - - - - - - - -

    label

    description of the axis

    max

    high edge of last bin

    min

    low edge of first bin

    n

    number of bins

    uoflow

    add underflow and overflow bins to the histogram for this axis or not

    -
  2. -
  3. regular_axis();
  4. -
  5. regular_axis(const regular_axis &);
  6. -
  7. regular_axis & operator=(const regular_axis &);
  8. -
-
-
-

-regular_axis public member functions

-
    -
  1. -
    int index(double x) const;
    Returns the bin index for the passed argument.
  2. -
  3. double operator[](int idx) const;
  4. -
  5. bool operator==(const regular_axis &) const;
  6. -
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/variable_axis.html b/doc/html/boost/histogram/variable_axis.html deleted file mode 100644 index 8b83524d..00000000 --- a/doc/html/boost/histogram/variable_axis.html +++ /dev/null @@ -1,134 +0,0 @@ - - - -Class variable_axis - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Class variable_axis

-

boost::histogram::variable_axis — An axis for real-valued data and bins of varying width. Binning is a O(log(N)) operation. If speed matters and the problem domain allows it, prefer a regular_axis.

-
-

Synopsis

-
// In header: <boost/histogram/axis.hpp>
-
-
-class variable_axis : public boost::histogram::axis_base,
-                      public boost::histogram::real_axis< variable_axis >
-{
-public:
-  // construct/copy/destruct
-  template<typename Container> 
-    explicit variable_axis(const Container &, 
-                           const std::string & = std::string(), bool = true);
-  template<typename Iterator> 
-    variable_axis(const Iterator &, const Iterator &, 
-                  const std::string & = std::string(), bool = true);
-  variable_axis();
-  variable_axis(const variable_axis &);
-  variable_axis & operator=(const variable_axis &);
-
-  // public member functions
-  int index(double) const;
-  double operator[](int) const;
-  bool operator==(const variable_axis &) const;
-};
-
-

Description

-
-

-variable_axis - public - construct/copy/destruct

-
    -
  1. -
    template<typename Container> 
    -  explicit variable_axis(const Container & x, 
    -                         const std::string & label = std::string(), 
    -                         bool uoflow = true);
    -

    Constructor

    -

    -

    -
    ---- - - - - -

    Parameters:

    ---- - - - - - - - - - - - - - - -

    label

    description of the axis

    uoflow

    add underflow and overflow bins to the histogram for this axis or not

    x

    An axis for real-valued data and bins of varying width. Binning is a O(log(N)) operation. If speed matters and the problem domain allows it, prefer a regular_axis.

    -
  2. -
  3. template<typename Iterator> 
    -  variable_axis(const Iterator & begin, const Iterator & end, 
    -                const std::string & label = std::string(), 
    -                bool uoflow = true);
  4. -
  5. variable_axis();
  6. -
  7. variable_axis(const variable_axis &);
  8. -
  9. variable_axis & operator=(const variable_axis &);
  10. -
-
-
-

-variable_axis public member functions

-
    -
  1. int index(double x) const;
  2. -
  3. double operator[](int idx) const;
  4. -
  5. bool operator==(const variable_axis &) const;
  6. -
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/visitor/bins.html b/doc/html/boost/histogram/visitor/bins.html deleted file mode 100644 index 067d9b93..00000000 --- a/doc/html/boost/histogram/visitor/bins.html +++ /dev/null @@ -1,62 +0,0 @@ - - - -Struct bins - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Struct bins

-

boost::histogram::visitor::bins

-
-

Synopsis

-
// In header: <boost/histogram/visitors.hpp>
-
-
-struct bins : public static_visitor< unsigned > {
-
-  // public member functions
-  template<typename A> unsigned operator()(const A &) const;
-};
-
-

Description

-
-

-bins public member functions

-
  1. template<typename A> unsigned operator()(const A & a) const;
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/visitor/cmp.html b/doc/html/boost/histogram/visitor/cmp.html deleted file mode 100644 index c36aac90..00000000 --- a/doc/html/boost/histogram/visitor/cmp.html +++ /dev/null @@ -1,66 +0,0 @@ - - - -Struct cmp - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Struct cmp

-

boost::histogram::visitor::cmp

-
-

Synopsis

-
// In header: <boost/histogram/visitors.hpp>
-
-
-struct cmp : public static_visitor< bool > {
-
-  // public member functions
-  template<typename T> bool operator()(const T &, const T &) const;
-  template<typename T, typename U> bool operator()(const T &, const U &) const;
-};
-
-

Description

-
-

-cmp public member functions

-
    -
  1. template<typename T> bool operator()(const T & a, const T & b) const;
  2. -
  3. template<typename T, typename U> bool operator()(const T &, const U &) const;
  4. -
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/visitor/index.html b/doc/html/boost/histogram/visitor/index.html deleted file mode 100644 index 74a51578..00000000 --- a/doc/html/boost/histogram/visitor/index.html +++ /dev/null @@ -1,74 +0,0 @@ - - - -Struct index - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Struct index

-

boost::histogram::visitor::index

-
-

Synopsis

-
// In header: <boost/histogram/visitors.hpp>
-
-
-struct index : public static_visitor< int > {
-  // construct/copy/destruct
-  index(double);
-
-  // public member functions
-  template<typename A> int operator()(const A &) const;
-
-  // public data members
-  double x;
-};
-
-

Description

-
-

-index - public - construct/copy/destruct

-
  1. index(double d);
-
-
-

-index public member functions

-
  1. template<typename A> int operator()(const A & a) const;
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/visitor/shape.html b/doc/html/boost/histogram/visitor/shape.html deleted file mode 100644 index a8448942..00000000 --- a/doc/html/boost/histogram/visitor/shape.html +++ /dev/null @@ -1,62 +0,0 @@ - - - -Struct shape - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Struct shape

-

boost::histogram::visitor::shape

-
-

Synopsis

-
// In header: <boost/histogram/visitors.hpp>
-
-
-struct shape : public static_visitor< unsigned > {
-
-  // public member functions
-  template<typename A> unsigned operator()(const A &) const;
-};
-
-

Description

-
-

-shape public member functions

-
  1. template<typename A> unsigned operator()(const A & a) const;
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost/histogram/visitor/uoflow.html b/doc/html/boost/histogram/visitor/uoflow.html deleted file mode 100644 index fb99d377..00000000 --- a/doc/html/boost/histogram/visitor/uoflow.html +++ /dev/null @@ -1,62 +0,0 @@ - - - -Struct uoflow - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-
-
-

Struct uoflow

-

boost::histogram::visitor::uoflow

-
-

Synopsis

-
// In header: <boost/histogram/visitors.hpp>
-
-
-struct uoflow : public static_visitor< bool > {
-
-  // public member functions
-  template<typename A> bool operator()(const A &) const;
-};
-
-

Description

-
-

-uoflow public member functions

-
  1. template<typename A> bool operator()(const A & a) const;
-
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_histogram/changelog.html b/doc/html/boost_histogram/changelog.html deleted file mode 100644 index 5a359b9c..00000000 --- a/doc/html/boost_histogram/changelog.html +++ /dev/null @@ -1,40 +0,0 @@ - - - -Changelog - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHome -
- - - - -
-
-
-PrevUpHome -
- - diff --git a/doc/html/boost_histogram/introduction.html b/doc/html/boost_histogram/introduction.html deleted file mode 100644 index 473595f5..00000000 --- a/doc/html/boost_histogram/introduction.html +++ /dev/null @@ -1,92 +0,0 @@ - - - -Introduction - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- Histograms are a basic tool in every statistical analysis. They compactly represent - a data set of one or several random variables with acceptable loss of information. - It is often more convenient to work with a histogram of a data distribution, - instead of the original distribution which may consume a lot of memory or disc - space. Interesting quantities like the mean, variance, or mode may be extracted - from the histogram instead of the original data set. -

-

- This library implements a single histogram class with a simple interface, which - can be used with 1, 2, 3 or N-dimensional data sets (the internal limit is - set to 16 dimensions). It supports normal counting and weighted counting, and - its provides a data-driven variance estimate for the sum of the counts in either - case. The histogram was written so that it just works, - to be efficient and safe to use in its application domain, completely hiding - the implementation details on how it does its counting (you, - the user, have more important things to worry about). -

-

- The histogram is implemented in C++ and has Python-bindings. It passes the - language barrier without copying its internal (possibly large) data buffer. - The language transparency allows users who do data analysis in Python to create - an empty histogram instance in Python, pass it over to a complex C++ code for - filling, then analyse the results:: -

-

-

-
import histogram as hg
-import complex_cpp_module
-
-h = hg.histogram(hg.regular_axis(100, 0, 1))
-
-complex_cpp_module.run_filling(h)
-
-# h is now filled with data,
-# continue with statistical analysis of h
-
-

-

-

- Histograms can be added if they have the same signature. This is convenient - if histograms are filled in parallel on a cluster and then merged (added). -

-

- The histogram can be serialized to disk for persistent storage from C++ and - pickled in Python. It comes with Numpy support, too. The histogram can be fast-filled - with Numpy arrays for maximum performance, and viewed as a Numpy array without - copying its memory buffer. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_histogram/motivation.html b/doc/html/boost_histogram/motivation.html deleted file mode 100644 index 1e6c028c..00000000 --- a/doc/html/boost_histogram/motivation.html +++ /dev/null @@ -1,64 +0,0 @@ - - - -Motivation - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- -

- There is a lack of a widely-used, free histogram class. While it is easy to - write an 1-dimensional histogram, writing an n-dimensional histogram poses - more of a challenge. If you add serialization and Python/Numpy support onto - the wish-list, the air becomes thin. -

-

- The main competitor is the ROOT framework. - The histogram in this project is designed to be more convenient to use, and - as fast or faster than the equivalent ROOT histograms. It comes without heavy - baggage, instead it has a clean and modern C++ design which follows the advice - given in popular C++ books, like those of Meyers - and Sutter and Alexandrescu. -

-

- Two of the main design goals are to conveniently hide the internal details - on how things are counted, and to use the same interface for 1-dimensional - and n-dimensional histograms. The count storage is an implementation detail, - chosen automatically to be fast and efficient. The histogram should just work, users shouldn't be forced to make choices - among several storage options everytime they encounter a new data set. -

-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_histogram/notes.html b/doc/html/boost_histogram/notes.html deleted file mode 100644 index b358cef2..00000000 --- a/doc/html/boost_histogram/notes.html +++ /dev/null @@ -1,526 +0,0 @@ - - - -Notes - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-

-Notes -

- -
- -
    -
  • - Boost -
  • -
  • - CMake -
  • -
  • - Optional dependencies* -
      -
    • - Python for Python - bindings -
    • -
    • - Numpy for Numpy support -
    • -
    • - Sphinx to (re)build - this documentation -
    • -
    -
  • -
-
-
- -

-

-
git clone https://github.com/HDembinski/histogram.git
-mkdir build && cd build
-cmake ../histogram/build
-make install
-
-

-

-

- Do make test - to run the tests, or ctest -V for - more output. -

-
- - - - - -
[Note]Note

- I couldn't figure out a proper way to install the Python module with CMake, - so for the time being, CMake will print a message with manual instructions - instead. The main problem is how to pick the right dist-packages path in - a platform-independent way, and such that it respects the CMAKE_INSTALL_PREFIX -

-
-
-

-Tests -

-

- Most of the C++ interface is implicitly tested in the tests of the Python - interface, which in turn calls the C++ interface. -

-
-
-

-Checks -

-

- Some checks are included in test/check. - These are not strictly tests, and not strictly examples, yet they provide - useful information that belongs with the library code. They are not build - by default, building can be activated with the CMake flag BUILD_CHECKS. -

-
-
- -

- The Python and C++ interface are indentical - except when they are not. The - exceptions concern cases where a more elegant and pythonic way of implementing - things exists. In a few cases, the C++ classes have extra member functions - for convenience, which are not needed on the Python side. -

-

- Properties Getter/setter-like functions are wrapped as properties. -

-

- Keyword-based parameters C++ member functions :cpp:func:histogram::fill - and :cpp:func:histogram::wfill are wrapped by the single Python - member function :py:func:histogram.fill with - an optional keyword parameter w - to pass a weight. -

-

- C++ convenience C++ member function :cpp:func:histogram::bins - is omitted on the Python side, since it is very easy to just query this directly - from the axis object in Python. On the C++ side, this would require a extra - type cast or applying a visitor. -

-
-
- -

- One design goal of this project is to be fast. The act of filling the histogram - with a number should be insignificant compared to the CPU cycles spend to - retrieve/generate that number. Naturally, we also want to beat the competition. -

-

- The following table shows results of a simple benchmark against -

-
    -
  • - TH1I, TH3I - and THnI of the ROOT framework -
  • -
  • - histogram and histogramdd from the Python module - numpy -
  • -
-

- The benchmark against ROOT is implemented in C++, the benchmark against numpy - in Python. -

-

- Remarks: -

-
    -
  • - The comparison with ROOT puts ROOT at the advantage, since TH1I and TH3I - are specialized classes for 1 dimension and 3 dimensions, not a general - class for N-dimensions like boost::histogram. - ROOT histograms also lack a comparably flexible system to define different - binning schemes for each axis. -
  • -
  • - Large vectors are pre-allocated and with random numbers drawn from a - uniform or normal distribution for all tests. In the timed part, these - numbers are read from the vector and put into the histograms. This reduces - the overhead merely to memory access. -
  • -
  • - The test with uniform random numbers never fills the overflow and underflow - bins, while the test with random numbers from a normal distribution does. - This explains some of the differences between the two distributions. -
  • -
  • - All tests are repeated 10 times, the minimum is shown. -
  • -
-
-

Table 1.1. Test system: Intel Core i7-4500U CPU clocked at 1.8 GHz, 8 GB of DDR3 - RAM

-
----- - - - - - - - - - - -
-

- distribution -

-
-

- uniform -

-
-

- normal -

-
-
-

Table 1.2. distribution

-
- - - - - - - - - -
-

- dimension -

-
-

- No. of fills -

-
-

- C++: ROOT [t/s] -

-
-

- C++: boost [t/s] -

-
-

- Py: numpy [t/s] -

-
-

- Py: boost [t/s] -

-
-
-
-
-
-

Table 1.3. uniform

-
----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- 1D -

-
-

- 3D -

-
-

- 6D -

-
-

- 12M -

-
-

- 4M -

-
-

- 2M -

-
-

- 0.127 -

-
-

- 0.199 -

-
-

- 0.185 -

-
-

- 0.172 -

-
-

- 0.177 -

-
-

- 0.155 -

-
-

- 0.825 -

-
-

- 0.727 -

-
-

- 0.436 -

-
-

- 0.209 -

-
-

- 0.229 -

-
-

- 0.192 -

-
-
-
-
-
-

Table 1.4. normal

-
----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

- 1D -

-
-

- 3D -

-
-

- 6D -

-
-

- 12M -

-
-

- 4M -

-
-

- 2M -

-
-

- 0.168 -

-
-

- 0.143 -

-
-

- 0.179 -

-
-

- 0.172 -

-
-

- 0.171 -

-
-

- 0.150 -

-
-

- 0.824 -

-
-

- 0.426 -

-
-

- 0.401 -

-
-

- 0.207 -

-
-

- 0.194 -

-
-

- 0.168 -

-
-
-
-
-
-

- boost::histogram::histogram - shows consistent performance comparable to the specialized ROOT histograms. - It is faster than ROOT's implementation of a N-dimensional histogram THnI. The performance of boost::histogram::histogram - is similar in C++ and Python, showing only a small overhead in Python. It - is consistently faster than numpy's histogram functions. -

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_histogram/rationale.html b/doc/html/boost_histogram/rationale.html deleted file mode 100644 index 4eb5f62e..00000000 --- a/doc/html/boost_histogram/rationale.html +++ /dev/null @@ -1,189 +0,0 @@ - - - -Rationale - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -

- I designed the histogram based on a decade of experience collected in working - with Big Data, more precisely in the field of particle physics and astroparticle - physics. In many ways, the ROOT <https://root.cern.ch>_ histograms served as an example of not to do it. -

-
- -
    -
  • - "Do one thing and do it well", Doug McIlroy -
  • -
  • - The Zen of Python - (also applies to other languages). -
  • -
-
-
- -

- A histogram should have the same consistent interface whatever the dimension. - Like std::vector it should just - work, users shouldn't be forced to make a - priori choices among several histogram classes and options everytime - they encounter a new data set. -

-
-
- -

- Python is a great language for data analysis, so the histogram needs Python - bindings. The histogram should be usable as an interface between a complex - simulation or data-storage system written in C++ and data-analysis/plotting - in Python: define the histogram in Python, let it be filled on the C++ side, - and then get it back for further data analysis or plotting. -

-

- Data analysis in Python is Numpy-based, so Numpy support is a must. -

-
-
- -

- The histogram supports half a dozent different binning strategies, conveniently - encapsulated in axis objects. There is the standard sorting of real-valued - data into bins of equal or varying width, but also binning of angles or integer - values. -

-

- Extra bins that count over- and underflow values are added by default. This - feature can be turned off individually for each axis. The extra bins do not - disturb normal bin counting. On an axis with n - bins, the first bin has the index 0, - the last bin n-1, while the under- and overflow bins are accessible - at -1 - and n, respectively. -

-
-
- -

- Dense storage in memory is a must for high performance. Unfortunately, the - curse - of dimensionality quickly become a problem as the number of dimensions - grows, leading to histograms which consume large amounts (up to GBs) of memory. -

-

- Fortunately, having many dimensions typically reduces the number of counts - per bin, since counts get spread over many dimensions. The histogram uses - an adaptive count size per bin to be as memory-efficient as possible, by - starting with the smallest integer size per bin of 1 byte and increasing - as needed to up to 8 byte. A std::vector - grows in length as new elements are added, - while the count storage grows in depth. -

-
-
- -

- A histogram categorizes and counts, so the natural choice for the data type - of the counts are integers. However, in particle physics, histograms are - also often filled with weighted events, for example, to make sure that two - histograms look the same in one variable, while the distribution of another, - correlated variable is a subject of study. -

-

- The histogram can be filled with either weighted or unweighted counts. In - the weighted case, the sum of weights is stored in a double. - The histogram provides a variance estimate is both cases. In the unweighted - case, the estimate is computed from the count itself, using Poisson-theory. - In the weighted case, the sum of squared weights is stored alongside the - sum of weights in a second double, - and used to compute a variance estimate. -

-
-
- -

- Serialization is implemented using boost::serialization. - Pickling in Python is implemented based on the C++ serialization code. To - ensure portability of the pickled histogram, the pickle string is an ASCII - representation of the histogram, generated with the boost::archive::text_oarchive. - It would be great to switch to a portable binary representation in the future, - when that becomes available. -

-

- To reduce the size of the string, run-length encoding is applied (zero-suppression) - to sequences of zeros. Partly filled histograms often contain large sequences - of zeros. -

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_histogram/references.html b/doc/html/boost_histogram/references.html deleted file mode 100644 index 9266fb8b..00000000 --- a/doc/html/boost_histogram/references.html +++ /dev/null @@ -1,56 +0,0 @@ - - - -References - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
- - - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/boost_histogram/tutorial.html b/doc/html/boost_histogram/tutorial.html deleted file mode 100644 index 0406dd62..00000000 --- a/doc/html/boost_histogram/tutorial.html +++ /dev/null @@ -1,191 +0,0 @@ - - - -Tutorial - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
- - -
- -

- How to make a 1d-histogram in C++ and to fill it: -

-
#include <boost/histogram/histogram.hpp>
-#include <boost/histogram/axis.hpp>
-#include <iostream>
-#include <cmath>
-
-int main(int, char**) {
-    namespace bh = boost::histogram;
-
-    /* Create a 1-d histogram with an axis that has 10 bins
-     * of equal width, covering the real line in the interval
-     * [-1.0, 2.0), label it 'x'.
-     * Several other binning strategies are supported, see
-     * documentation of axis_types.
-     */
-    bh::histogram h(bh::regular_axis(10, -1.0, 2.0, "x"));
-
-    /* Fill histogram with a few entries. Values outside of
-     * axis are placed in the overflow and underflow bins.
-     * Normally you would loop over a source of values.
-     */
-    h.fill(-1.5); // put in underflow bin
-    h.fill(-0.5);
-    h.fill(1.1);
-    h.fill(-1.0); // included, interval is semi-open
-    h.fill(0.3);
-    h.fill(1.7);
-    h.fill(2.0);  // put in overflow bin, interval is semi-open
-    h.fill(20.0); // put in overflow bin
-
-    /* Fill histogram with a weighted count. This increases the
-     * bin counter not by one, but by the specified weight.
-     *
-     * This call transparently causes histogram to change it memory
-     * layout to store counts as doubles instead of integers. The
-     * layout for weighted counts requires up to 16x more memory
-     * and will cause inaccuracies of the type a + 1 == a if a is
-     * sufficiently large.
-     *
-     * Use wfill(...) if you have to, else prefer fill(...).
-     */
-    h.wfill(0.1, 5.0);
-
-    /* Print a table representation of the histogram showing the bin
-     * value and a estimate of the standard deviation. Overflow and
-     * Underflow bins are accessed naturally as the bins -1 and 10.
-     */
-    for (int i = -1; i <= h.bins(0); ++i) {
-        const bh::regular_axis& a = h.axis<bh::regular_axis>(0);
-        std::cout << "bin " << i
-                  << " x in [" << a[i] << ", " << a[i+1] << "): "
-                  << h.value(i) << " +/- " << std::sqrt(h.variance(i))
-                  << std::endl;
-    }
-}
-
-

-

-

- The program output is: -

-

-

-
bin -1 x in [-inf, -1): 1 +/- 1
-bin 0 x in [-1, -0.7): 1 +/- 1
-bin 1 x in [-0.7, -0.4): 1 +/- 1
-bin 2 x in [-0.4, -0.1): 0 +/- 0
-bin 3 x in [-0.1, 0.2): 5 +/- 5
-bin 4 x in [0.2, 0.5): 1 +/- 1
-bin 5 x in [0.5, 0.8): 0 +/- 0
-bin 6 x in [0.8, 1.1): 0 +/- 0
-bin 7 x in [1.1, 1.4): 1 +/- 1
-bin 8 x in [1.4, 1.7): 0 +/- 0
-bin 9 x in [1.7, 2): 1 +/- 1
-bin 10 x in [2, inf): 2 +/- 1.41421
-
-

-

-
-
- -

- How to make a 2d-histogram in Python and to fill it using a Numpy array: -

-

-

-
import histogram as bh
-import numpy as np
-
-# create a 2d-histogram without underflow and overflow bins
-# for polar coordinates, using a specialized polar_axis for
-# the binning of the angle 'phi'
-#
-# radial axis with label 'radius' has 10 bins from 0.0 to 5.0
-# polar axis with label 'phi' has 4 bins and a phase of 0.0
-h = bh.histogram(bh.regular_axis(10, 0.0, 5.0, "radius",
-                                 uoflow=False),
-                 bh.polar_axis(4, 0.0, "phi"))
-
-# fill histogram with random values, using numpy to make 
-# a two-dimensional normal distribution in cartesian coordinates
-x = np.random.randn(1000)             # generate x
-y = np.random.randn(1000)             # generate y
-rphi = np.empty((1000, 2))
-rphi[:, 0] = (x ** 2 + y ** 2) ** 0.5 # compute radius
-rphi[:, 1] = np.arctan2(y, x)         # compute phi
-h.fill(rphi)
-
-# access counts as a numpy array (no data is copied)
-count_matrix = np.asarray(h)
-
-print count_matrix
-
-

- The program output are the counts per bin as a 2d-array: -

-

-

-
[[37 26 33 37]
- [60 69 76 62]
- [48 80 80 77]
- [38 49 45 49]
- [22 24 20 23]
- [ 7  9  9  8]
- [ 3  2  3  3]
- [ 0  0  0  0]
- [ 0  1  0  0]
- [ 0  0  0  0]]
-
-

-

-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/histogram/reference.html b/doc/html/histogram/reference.html deleted file mode 100644 index daa5fc19..00000000 --- a/doc/html/histogram/reference.html +++ /dev/null @@ -1,150 +0,0 @@ - - - -Reference - - - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
-PrevUpHomeNext -
-
-

-Reference

- -
- -

Includes all the non-experimental headers of the Boost.histogram library.

-

The library consists of a single histogram and several axis types which are stored in a boost::variant called axis_type The axis types are created and passed to the constructor of the histogram to define its binning scheme. All following types are embedded in the boost::histogram namespace, which is omitted for brevity.

-
-
- -

Defines the core class of this library, boost::histogram::histogram .

-
-
-BOOST_HISTOGRAM_CTOR(z, n, unused)
-BOOST_HISTOGRAM_FILL(z, n, unused)
-BOOST_HISTOGRAM_WFILL(z, n, unused)
-BOOST_HISTOGRAM_VALUE(z, n, unused)
-BOOST_HISTOGRAM_VARIANCE(z, n, unused)
-
namespace boost {
-  namespace histogram {
-    class histogram;
-    histogram operator+(const histogram & a, const histogram & b);
-  }
-}
-
-
- -
namespace boost {
-  namespace histogram {
-    class axis_base;
-    template<typename Derived> class real_axis;
-    class regular_axis;
-    class polar_axis;
-    class variable_axis;
-    class category_axis;
-    class integer_axis;
-
-    typedef variant< regular_axis, polar_axis, variable_axis, category_axis, integer_axis > axis_type;
-    std::ostream & operator<<(std::ostream &, const regular_axis &);
-    std::ostream & operator<<(std::ostream &, const polar_axis &);
-    std::ostream & operator<<(std::ostream &, const variable_axis &);
-    std::ostream & operator<<(std::ostream &, const category_axis &);
-    std::ostream & operator<<(std::ostream &, const integer_axis &);
-  }
-}
-
-
- -
-
-BOOST_HISTOGRAM_AXIS_LIMIT
-BOOST_HISTOGRAM_BASE_APPEND(z, n, unused)
-BOOST_HISTOGRAM_BASE_CTOR(z, n, unused)
-
namespace boost {
-  namespace histogram {
-    class basic_histogram;
-  }
-}
-
-
- -

Defines the serialization functions, to use with boost.serialize.

-
namespace boost {
-  namespace histogram {
-    template<typename Archive> 
-      void serialize(Archive & ar, axis_base & base, unsigned version);
-    template<typename Archive> 
-      void serialize(Archive & ar, regular_axis & axis, unsigned version);
-    template<typename Archive> 
-      void serialize(Archive & ar, polar_axis & axis, unsigned version);
-    template<typename Archive> 
-      void serialize(Archive & ar, variable_axis & axis, unsigned version);
-    template<typename Archive> 
-      void serialize(Archive & ar, category_axis & axis, unsigned version);
-    template<typename Archive> 
-      void serialize(Archive & ar, integer_axis & axis, unsigned version);
-    template<typename Archive> 
-      void serialize(Archive & ar, basic_histogram & h, unsigned version);
-    template<typename Archive> 
-      void serialize(Archive & ar, histogram & h, unsigned version);
-  }
-}
-
-
- -
namespace boost {
-  namespace histogram {
-    namespace visitor {
-      struct bins;
-      struct shape;
-      struct uoflow;
-      struct index;
-      struct cmp;
-    }
-  }
-}
-
-
- - - -
-
-
-PrevUpHomeNext -
- - diff --git a/doc/html/index.html b/doc/html/index.html deleted file mode 100644 index ae17b584..00000000 --- a/doc/html/index.html +++ /dev/null @@ -1,115 +0,0 @@ - - - -Chapter 1. Boost.Histogram - - - - - - - - - - - - - -
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
-
-
Next
-
-
-

-Chapter 1. Boost.Histogram

-

-Hans Dembinski -

-
-
-

- 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) -

-
-
- -
- -

- This project contains an easy-to-use powerful n-dimensional histogram class - implemented in C++03, optimized for convenience and excellent performance under - heavy duty. Move semantics are supported using boost::move. The - histogram has a complete C++ and a Python - interface, and can be passed over the language boundary with ease. Numpy - is fully supported; histograms can be filled with Numpy arrays at C speeds - and are convertible into Numpy arrays without copying data. Histograms can - be streamed from/to files and pickled in Python. -

-

- My goal is to submit this project to the Boost - Libraries -

-
-
- - - -

Last revised: July 12, 2016 at 22:56:41 GMT

-
-
Next
- - diff --git a/doc/html/standalone_HTML.manifest b/doc/html/standalone_HTML.manifest deleted file mode 100644 index 463ee72f..00000000 --- a/doc/html/standalone_HTML.manifest +++ /dev/null @@ -1,31 +0,0 @@ -index.html -boost_histogram/motivation.html -boost_histogram/introduction.html -boost_histogram/tutorial.html -boost_histogram/notes.html -boost_histogram/rationale.html -boost_histogram/references.html -histogram/reference.html -boost/histogram/histogram.html -BOOST_HISTOGRAM_CTOR.html -BOOST_HISTOGRAM_FILL.html -BOOST_HISTOGRAM_WFILL.html -BOOST_HISTOGRAM_VALUE.html -BOOST_HISTOGRAM_VARIANCE.html -boost/histogram/axis_base.html -boost/histogram/real_axis.html -boost/histogram/regular_axis.html -boost/histogram/polar_axis.html -boost/histogram/variable_axis.html -boost/histogram/category_axis.html -boost/histogram/integer_axis.html -boost/histogram/basic_histogram.html -BOOST_HISTOGRAM_AXIS_LIMIT.html -BOOST_HISTOGRAM_BASE_APPEND.html -BOOST_HISTOGRAM_BASE_CTOR.html -boost/histogram/visitor/bins.html -boost/histogram/visitor/shape.html -boost/histogram/visitor/uoflow.html -boost/histogram/visitor/index.html -boost/histogram/visitor/cmp.html -boost_histogram/changelog.html diff --git a/doc/index.qbk b/doc/index.qbk deleted file mode 100644 index caa3f63d..00000000 --- a/doc/index.qbk +++ /dev/null @@ -1,40 +0,0 @@ -Histogram -========= - -Copyright (c) 2016 Hans Dembinski - -Distributed under the `Boost Software License, Version 1.0 `_, see accompanying file LICENSE. - -Authors -------- -Hans Dembinski -Klemens Morgentau - -Description ------------ - -This project contains an easy-to-use powerful n-dimensional histogram class implemented in ``C++03``, optimized for convenience and excellent performance under heavy duty. Move semantics are supported using `boost::move`. The histogram has a complete C++ and a `Python `_ interface, and can be passed over the language boundary with ease. `Numpy `_ is fully supported; histograms can be filled with Numpy arrays at C speeds and are convertible into Numpy arrays without copying data. Histograms can be streamed from/to files and pickled in Python. - -My goal is to submit this project to the `Boost Libraries `_. - -Contents --------- - -.. toctree:: - :maxdepth: 2 - - motivation - intro - tutorial - notes - types - rationale - references - changelog - -.. Indices and tables -.. ================== - -.. * :ref:`genindex` -.. * :ref:`modindex` -.. * :ref:`search` diff --git a/doc/intro.qbk b/doc/intro.qbk deleted file mode 100644 index 74a690c3..00000000 --- a/doc/intro.qbk +++ /dev/null @@ -1,28 +0,0 @@ -[section Introduction] - -Histograms are a basic tool in every statistical analysis. They compactly represent a data set of one or several random variables with acceptable loss of information. It is often more convenient to work with a histogram of a data distribution, instead of the original distribution which may consume a lot of memory or disc space. Interesting quantities like the mean, variance, or mode may be extracted from the histogram instead of the original data set. - -This library implements a single histogram class with a simple interface, which can be used with 1, 2, 3 or N-dimensional data sets (the internal limit is set to 16 dimensions). It supports normal counting and weighted counting, and its provides a data-driven variance estimate for the sum of the counts in either case. The histogram was written so that it *just works*, to be efficient and safe to use in its application domain, completely hiding the implementation details on how it does its counting (*you*, the user, have more important things to worry about). - -The histogram is implemented in C++ and has Python-bindings. It passes the language barrier without copying its internal (possibly large) data buffer. The language transparency allows users who do data analysis in Python to create an empty histogram instance in Python, pass it over to a complex C++ code for filling, then analyse the results:: - -[python] -`` - - import histogram as hg - import complex_cpp_module - - h = hg.histogram(hg.regular_axis(100, 0, 1)) - - complex_cpp_module.run_filling(h) - - # h is now filled with data, - # continue with statistical analysis of h - -`` - -Histograms can be added if they have the same signature. This is convenient if histograms are filled in parallel on a cluster and then merged (added). - -The histogram can be serialized to disk for persistent storage from C++ and pickled in Python. It comes with Numpy support, too. The histogram can be fast-filled with Numpy arrays for maximum performance, and viewed as a Numpy array without copying its memory buffer. - -[endsect] \ No newline at end of file diff --git a/doc/motivation.qbk b/doc/motivation.qbk deleted file mode 100644 index e3a1f594..00000000 --- a/doc/motivation.qbk +++ /dev/null @@ -1,9 +0,0 @@ -[section:motivation Motivation] - -There is a lack of a widely-used, free histogram class. While it is easy to write an 1-dimensional histogram, writing an n-dimensional histogram poses more of a challenge. If you add serialization and Python/Numpy support onto the wish-list, the air becomes thin. - -The main competitor is the [@https://root.cern.ch ROOT framework]. The histogram in this project is designed to be more convenient to use, and as fast or faster than the equivalent ROOT histograms. It comes without heavy baggage, instead it has a clean and modern C++ design which follows the advice given in popular C++ books, like those of [@http://www.aristeia.com/books.html Meyers] and [@http://www.gotw.ca/publications/c++cs.htm Sutter and Alexandrescu]. - -Two of the main design goals are to conveniently hide the internal details on how things are counted, and to use the same interface for 1-dimensional and n-dimensional histograms. The count storage is an implementation detail, chosen automatically to be fast and efficient. The histogram should *just work*, users shouldn't be forced to make choices among several storage options everytime they encounter a new data set. - -[endsect] \ No newline at end of file diff --git a/doc/notes.qbk b/doc/notes.qbk deleted file mode 100644 index 035cf47e..00000000 --- a/doc/notes.qbk +++ /dev/null @@ -1,113 +0,0 @@ -[section:notes Notes] - -[section:dependencies Dependencies] - - -* [@http://www.boost.org Boost] -* [@https://cmake.org CMake] - -* [*Optional dependencies*] - - * [@`_ histograms served as an example of *not to do it*. - -[section Design principles] - -* "Do one thing and do it well", Doug McIlroy -* The [@https://www.python.org/dev/peps/pep-0020 Zen of Python] (also applies to other languages). - -[endsect] -[section Interface convenience] - -A histogram should have the same consistent interface whatever the dimension. Like `std::vector` it should *just work*, users shouldn't be forced to make *a priori* choices among several histogram classes and options everytime they encounter a new data set. - -[endsect] -[section Language transparency] - -Python is a great language for data analysis, so the histogram needs Python bindings. The histogram should be usable as an interface between a complex simulation or data-storage system written in C++ and data-analysis/plotting in Python: define the histogram in Python, let it be filled on the C++ side, and then get it back for further data analysis or plotting. - -Data analysis in Python is Numpy-based, so Numpy support is a must. - -[endsect] -[section Powerful binning strategies] - -The histogram supports half a dozent different binning strategies, conveniently encapsulated in axis objects. There is the standard sorting of real-valued data into bins of equal or varying width, but also binning of angles or integer values. - -Extra bins that count over- and underflow values are added by default. This feature can be turned off individually for each axis. The extra bins do not disturb normal bin counting. On an axis with `n` bins, the first bin has the index `0`, the last bin `n-1`, while the under- and overflow bins are accessible at `-1` and `n`, respectively. - -[endsect] -[section Performance and memory-efficiency] - -Dense storage in memory is a must for high performance. Unfortunately, the [@https://en.wikipedia.org/wiki/Curse_of_dimensionality curse of dimensionality] quickly become a problem as the number of dimensions grows, leading to histograms which consume large amounts (up to GBs) of memory. - -Fortunately, having many dimensions typically reduces the number of counts per bin, since counts get spread over many dimensions. The histogram uses an adaptive count size per bin to be as memory-efficient as possible, by starting with the smallest integer size per bin of 1 byte and increasing as needed to up to 8 byte. A `std::vector` grows in *length* as new elements are added, while the count storage grows in *depth*. - -[endsect] -[section Weighted counts and variance estimates] - -A histogram categorizes and counts, so the natural choice for the data type of the counts are integers. However, in particle physics, histograms are also often filled with weighted events, for example, to make sure that two histograms look the same in one variable, while the distribution of another, correlated variable is a subject of study. - -The histogram can be filled with either weighted or unweighted counts. In the weighted case, the sum of weights is stored in a `double`. The histogram provides a variance estimate is both cases. In the unweighted case, the estimate is computed from the count itself, using Poisson-theory. In the weighted case, the sum of squared weights is stored alongside the sum of weights in a second `double`, and used to compute a variance estimate. - -[endsect] -[section Serialization and zero-suppression] - -Serialization is implemented using `boost::serialization`. Pickling in Python is implemented based on the C++ serialization code. To ensure portability of the pickled histogram, the pickle string is an ASCII representation of the histogram, generated with the `boost::archive::text_oarchive`. It would be great to switch to a portable binary representation in the future, when that becomes available. - -To reduce the size of the string, run-length encoding is applied (zero-suppression) to sequences of zeros. Partly filled histograms often contain large sequences of zeros. - -[endsect] -[endsect] \ No newline at end of file diff --git a/doc/references.qbk b/doc/references.qbk deleted file mode 100644 index d394b1f6..00000000 --- a/doc/references.qbk +++ /dev/null @@ -1,7 +0,0 @@ -[section References] - -* [@https://root.cern.ch ROOT framework] -* [@https://en.wikipedia.org/wiki/Poisson_distribution Poisson distribution] -* [@https://en.wikipedia.org/wiki/Propagation_of_uncertainty Uncertainty propagation] - -[endsect] \ No newline at end of file diff --git a/doc/sphinx/conf.py.in b/doc/sphinx/conf.py.in deleted file mode 100644 index 237b4568..00000000 --- a/doc/sphinx/conf.py.in +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- - -import sys -import os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.insert(0, os.path.abspath("@CMAKE_BINARY_DIR@")) - -# -- General configuration ------------------------------------------------ -extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.mathjax', - 'sphinx.ext.githubpages', -] -templates_path = ['_templates'] -source_suffix = '.rst' -source_encoding = 'utf-8-sig' -master_doc = 'index' -project = u'histogram' -copyright = u'2016, Hans Dembinski' -author = u'Hans Dembinski' -version = u'1.0' # The short X.Y version. -release = u'1.0' # The full version, including alpha/beta/rc tags. -language = None -exclude_patterns = [] -pygments_style = 'sphinx' -todo_include_todos = True - -# -- Options for HTML output ---------------------------------------------- -html_theme = 'alabaster' -html_theme_options = { - 'github_user': 'HDembinski', - 'github_repo': 'histogram', -} -html_last_updated_fmt = '%b %d, %Y' -html_use_smartypants = True -html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'relations.html' - ] -} -html_copy_source = False -htmlhelp_basename = 'histogramdoc' - -# -- Options for Epub output ---------------------------------------------- -epub_title = project -epub_author = author -epub_publisher = author -epub_copyright = copyright -epub_exclude_files = ['search.html'] diff --git a/doc/sphinx/types.rst b/doc/sphinx/types.rst deleted file mode 100644 index 573cfa71..00000000 --- a/doc/sphinx/types.rst +++ /dev/null @@ -1,54 +0,0 @@ -Python interface -^^^^^^^^^^^^^^^^ - -The operators ``==``, ``+=``, and ``+`` are defined for histograms. They are also pickable. - -.. py:module:: histogram - -.. autoclass:: histogram - - .. py:method:: __init__(*axes) - - Pass one or more axis objects as arguments to define the dimensions of the histogram. - - .. autoattribute:: dim - - .. automethod:: shape - - .. automethod:: axis - - .. py:method:: fill(*values, w=None) - - Pass a sequence of values with a length ``n`` is equal to the dimensions of the histogram, and optionally a weight :py:obj:`w` for this fill (*int* or *float*). - - If Numpy support is enabled, :py:obj:`values` my also be a 2d-array of shape ``(m, n)``, where ``m`` is the number of tuples to pass at once, and optionally another a second 1d-array :py:obj:`w` of shape ``(m,)``. - - .. py:method:: value(*indices) - - :param int indices: indices of the bin - :return: count for the bin - - .. py:method:: variance(*indices) - - :param int indices: indices of the bin - :return: variance estimate for the bin - - - -All axis types support the operators ``==`` and ``[]``. They support the :py:func:`len` and :py:func:`repr` calls, and the iterator protocol. - -.. autoclass:: regular_axis - :members: - -.. autoclass:: polar_axis - :members: - -.. autoclass:: variable_axis - :members: - -.. autoclass:: category_axis - :members: - -.. autoclass:: integer_axis - :members: - diff --git a/doc/tutorial.qbk b/doc/tutorial.qbk deleted file mode 100644 index e51119ee..00000000 --- a/doc/tutorial.qbk +++ /dev/null @@ -1,138 +0,0 @@ -[section Tutorial] - -[section Example 1: 1d-histogram in C++] - -How to make a 1d-histogram in C++ and to fill it: -[c++] -`` - - #include - #include - #include - #include - - int main(int, char**) { - namespace bh = boost::histogram; - - /* Create a 1-d histogram with an axis that has 10 bins - * of equal width, covering the real line in the interval - * [-1.0, 2.0), label it 'x'. - * Several other binning strategies are supported, see - * documentation of axis_types. - */ - bh::histogram h(bh::regular_axis(10, -1.0, 2.0, "x")); - - /* Fill histogram with a few entries. Values outside of - * axis are placed in the overflow and underflow bins. - * Normally you would loop over a source of values. - */ - h.fill(-1.5); // put in underflow bin - h.fill(-0.5); - h.fill(1.1); - h.fill(-1.0); // included, interval is semi-open - h.fill(0.3); - h.fill(1.7); - h.fill(2.0); // put in overflow bin, interval is semi-open - h.fill(20.0); // put in overflow bin - - /* Fill histogram with a weighted count. This increases the - * bin counter not by one, but by the specified weight. - * - * This call transparently causes histogram to change it memory - * layout to store counts as doubles instead of integers. The - * layout for weighted counts requires up to 16x more memory - * and will cause inaccuracies of the type a + 1 == a if a is - * sufficiently large. - * - * Use wfill(...) if you have to, else prefer fill(...). - */ - h.wfill(0.1, 5.0); - - /* Print a table representation of the histogram showing the bin - * value and a estimate of the standard deviation. Overflow and - * Underflow bins are accessed naturally as the bins -1 and 10. - */ - for (int i = -1; i <= h.bins(0); ++i) { - const bh::regular_axis& a = h.axis(0); - std::cout << "bin " << i - << " x in [" << a[i] << ", " << a[i+1] << "): " - << h.value(i) << " +/- " << std::sqrt(h.variance(i)) - << std::endl; - } - } - -`` - -The program output is: - -[teletype] - -`` - - bin -1 x in [-inf, -1): 1 +/- 1 - bin 0 x in [-1, -0.7): 1 +/- 1 - bin 1 x in [-0.7, -0.4): 1 +/- 1 - bin 2 x in [-0.4, -0.1): 0 +/- 0 - bin 3 x in [-0.1, 0.2): 5 +/- 5 - bin 4 x in [0.2, 0.5): 1 +/- 1 - bin 5 x in [0.5, 0.8): 0 +/- 0 - bin 6 x in [0.8, 1.1): 0 +/- 0 - bin 7 x in [1.1, 1.4): 1 +/- 1 - bin 8 x in [1.4, 1.7): 0 +/- 0 - bin 9 x in [1.7, 2): 1 +/- 1 - bin 10 x in [2, inf): 2 +/- 1.41421 -`` - -[endsect] -[section Example 2: 2d-histogram in Python] - -How to make a 2d-histogram in Python and to fill it using a Numpy array: - -[python] - -`` - import histogram as bh - import numpy as np - - # create a 2d-histogram without underflow and overflow bins - # for polar coordinates, using a specialized polar_axis for - # the binning of the angle 'phi' - # - # radial axis with label 'radius' has 10 bins from 0.0 to 5.0 - # polar axis with label 'phi' has 4 bins and a phase of 0.0 - h = bh.histogram(bh.regular_axis(10, 0.0, 5.0, "radius", - uoflow=False), - bh.polar_axis(4, 0.0, "phi")) - - # fill histogram with random values, using numpy to make - # a two-dimensional normal distribution in cartesian coordinates - x = np.random.randn(1000) # generate x - y = np.random.randn(1000) # generate y - rphi = np.empty((1000, 2)) - rphi[:, 0] = (x ** 2 + y ** 2) ** 0.5 # compute radius - rphi[:, 1] = np.arctan2(y, x) # compute phi - h.fill(rphi) - - # access counts as a numpy array (no data is copied) - count_matrix = np.asarray(h) - - print count_matrix - -`` -The program output are the counts per bin as a 2d-array: - -`` - [[37 26 33 37] - [60 69 76 62] - [48 80 80 77] - [38 49 45 49] - [22 24 20 23] - [ 7 9 9 8] - [ 3 2 3 3] - [ 0 0 0 0] - [ 0 1 0 0] - [ 0 0 0 0]] - -`` -[endsect] -[endsect] \ No newline at end of file diff --git a/include/boost/histogram.hpp b/include/boost/histogram.hpp index ef71eb07..30906026 100644 --- a/include/boost/histogram.hpp +++ b/include/boost/histogram.hpp @@ -8,7 +8,6 @@ #define BOOST_HISTOGRAM_HPP_ #include -#include /** * \file boost/histogram.hpp diff --git a/include/boost/histogram/axis.hpp b/include/boost/histogram/axis.hpp index fac48ca1..db242d04 100644 --- a/include/boost/histogram/axis.hpp +++ b/include/boost/histogram/axis.hpp @@ -150,9 +150,8 @@ public: * \param label description of the axis * \param uoflow add underflow and overflow bins to the histogram for this axis or not */ - template explicit - variable_axis(const Container& x, + variable_axis(const std::initializer_list& x, const std::string& label = std::string(), bool uoflow = true) : axis_base(x.size() - 1, label, uoflow), @@ -173,9 +172,11 @@ public: std::sort(x_.get(), x_.get() + bins() + 1); } - variable_axis() {} + variable_axis() = default; variable_axis(const variable_axis&); + variable_axis(variable_axis&&) = default; variable_axis& operator=(const variable_axis&); + variable_axis& operator=(variable_axis&&) = default; inline int index(double x) const { return std::upper_bound(x_.get(), x_.get() + bins() + 1, x) @@ -196,22 +197,19 @@ private: class category_axis { public: typedef std::string value_type; - /**Construct from a single string - * - * @param categories a string of categories separated by the character \a ; - */ - explicit - category_axis(const std::string& categories); - /**Construct from a single string + + /**Construct from initializer list of strings * * @param categories an ordered sequence of categories that this axis discriminates */ explicit - category_axis(const std::vector& categories); + category_axis(const std::initializer_list& categories); category_axis() {} category_axis(const category_axis&); + category_axis(category_axis&&) = default; category_axis& operator=(const category_axis&); + category_axis& operator=(category_axis&&) = default; inline int bins() const { return categories_.size(); } @@ -237,7 +235,12 @@ private: class integer_axis: public axis_base { public: typedef int value_type; - ///Constructor + + /**Construct axis over consecutive sequence of integers + * + * @param min smallest integer of the covered range + * @param max largest integer of the covered range + */ integer_axis(int min, int max, const std::string& label = std::string(), bool uoflow = true); @@ -263,33 +266,46 @@ private: namespace detail { struct linearize : public static_visitor { - typedef uintptr_t size_type; - double x; - int j; - size_type k, stride; - - linearize() : - x(std::numeric_limits::quiet_NaN()), - j(0), - k(0), - stride(1) - {} + int in; + std::size_t out = 0, stride = 1; template void operator()(const A& a) { - if (k < size_type(-1)) { - if (!std::isnan(x)) - j = a.index(x); + if (out < std::size_t(-1)) { const int bins = a.bins(); const int range = bins + 2 * a.uoflow(); - // the following three lines work for any overflow setting - j += (j < 0) * (bins + 2); // wrap around if j < 0 - if (j < range) { - k += j * stride; + // the following three lines worout for any overflow setting + in += (in < 0) * (bins + 2); // wrap around if in < 0 + if (in < range) { + out += in * stride; stride *= range; } else { - k = size_type(-1); // indicate out of range + out = std::size_t(-1); // indicate out of range + } + } + } + }; + + struct linearize_x : public static_visitor + { + double in; + std::size_t out = 0, stride = 1; + + template + void operator()(const A& a) { + if (out < std::size_t(-1)) { + int j = a.index(in); + const int bins = a.bins(); + const int range = bins + 2 * a.uoflow(); + // the following three lines worout for any overflow setting + j += (j < 0) * (bins + 2); // wrap around if j < 0 + if (j < range) { + out += j * stride; + stride *= range; + } + else { + out = std::size_t(-1); // indicate out of range } } } @@ -302,14 +318,14 @@ typedef variant< variable_axis, category_axis, integer_axis -> axis_type; +> axis_t; +// axis_t is automatically output-streamable if all its bounded types are std::ostream& operator<<(std::ostream&, const regular_axis&); std::ostream& operator<<(std::ostream&, const polar_axis&); std::ostream& operator<<(std::ostream&, const variable_axis&); std::ostream& operator<<(std::ostream&, const category_axis&); std::ostream& operator<<(std::ostream&, const integer_axis&); -// axis_type is automatically output-streamable if all its bounded types are } } diff --git a/include/boost/histogram/basic_histogram.hpp b/include/boost/histogram/basic_histogram.hpp deleted file mode 100644 index b1827a7f..00000000 --- a/include/boost/histogram/basic_histogram.hpp +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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_HISTOGRAM_BASE_HPP_ -#define _BOOST_HISTOGRAM_BASE_HPP_ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#if !defined(BOOST_HISTOGRAM_AXIS_LIMIT) -#define BOOST_HISTOGRAM_AXIS_LIMIT 16 -#endif - -namespace boost { -namespace histogram { - -/// This class holds collection of axis instances and computes the internal index -class basic_histogram { - BOOST_COPYABLE_AND_MOVABLE(basic_histogram) -public: - typedef container::vector axes_type; - typedef uintptr_t size_type; - - ~basic_histogram() {} - - // copy semantics (implementation needs to be here, workaround for gcc-bug) - basic_histogram(const basic_histogram& o) : - axes_(o.axes_) {} - - basic_histogram& operator=(BOOST_COPY_ASSIGN_REF(basic_histogram) o) - { if (this != &o) axes_ = o.axes_; return *this; } - - // move semantics (implementation needs to be here, workaround for gcc-bug) - basic_histogram(BOOST_RV_REF(basic_histogram) o) : - axes_() - { std::swap(axes_, o.axes_); } - - basic_histogram& operator=(BOOST_RV_REF(basic_histogram) o) - { if (this != &o) std::swap(axes_, o.axes_); return *this; } - - ///Returns the number of dimensions of the histogram, how many axis it has - unsigned dim() const { return axes_.size(); } - ///Returns the number of bins for axis \a i. - int bins(unsigned i) const { return apply_visitor(visitor::bins(), axes_[i]); } - /**Returns the actual number of fields used by the axis. If the axis has no - * underflow and overflow bins, this is equal to \a bins. Otherwise, the number is larger by 2. - */ - unsigned shape(unsigned i) const { return apply_visitor(visitor::shape(), axes_[i]); } - - template - typename enable_if, T&>::type - axis(unsigned i) { return axes_[i]; } - - template - typename disable_if, T&>::type - axis(unsigned i) { return boost::get(axes_[i]); } - - template - typename enable_if, const T&>::type - axis(unsigned i) const { return axes_[i]; } - - template - typename disable_if, const T&>::type - axis(unsigned i) const { return boost::get(axes_[i]); } - -#if defined(BOOST_HISTOGRAM_DOXYGEN) - /** Returns the axis object at index \a i, casted to type \a T. - * A runtime exception is thrown if the type cast is invalid. - */ - template T& axis(unsigned i); - /** The ``const``-version of the previous member function. */ - template const T& axis(unsigned i) const -#endif - -protected: - basic_histogram() {} - explicit basic_histogram(const axes_type& axes); - -#define BOOST_HISTOGRAM_BASE_APPEND(z, n, unused) axes_.push_back(a ## n); -#define BOOST_HISTOGRAM_BASE_CTOR(z, n, unused) \ - basic_histogram( BOOST_PP_ENUM_PARAMS_Z(z, n, const axis_type& a) ) \ - { \ - axes_.reserve(n); \ - BOOST_PP_REPEAT(n, BOOST_HISTOGRAM_BASE_APPEND, unused) \ - } - -// generates constructors taking 1 to AXIS_LIMIT arguments -BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_HISTOGRAM_AXIS_LIMIT), BOOST_HISTOGRAM_BASE_CTOR, nil) - - bool operator==(const basic_histogram&) const; - - template - inline - size_type pos(const Iterator& begin, const Iterator & end) const { - detail::linearize lin; - int i = axes_.size(); - Iterator itr = end; - while (i--) { - lin.x = *(--itr); - apply_visitor(lin, axes_[i]); - } - return lin.k; - } - - template - inline - size_type linearize(const Iterator &begin, const Iterator & end) const { - detail::linearize lin; - int i = axes_.size(); - Iterator itr = end; - while (i--) { - lin.j = *(--itr); - apply_visitor(lin, axes_[i]); - } - return lin.k; - } - - /// Returns the number of fields needed for storage - size_type field_count() const; - -private: - axes_type axes_; - - template - friend void serialize(Archive& ar, basic_histogram & h, unsigned version); -}; - -} -} - -#endif diff --git a/include/boost/histogram/histogram.hpp b/include/boost/histogram/histogram.hpp index d0f188be..6dc9a207 100644 --- a/include/boost/histogram/histogram.hpp +++ b/include/boost/histogram/histogram.hpp @@ -9,288 +9,175 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include #include +#include -/** \file boost/histogram/histogram.hpp - * \brief Defines the core class of this library, \ref boost::histogram::histogram . - * - */ +#define DEBUG(x) std::cout << #x << " " << x << std::endl +#define TRACE(msg) std::cout << __LINE__ << " " msg << std::endl namespace boost { namespace histogram { -/** The class implements an n-dimensional histogram, managing counts in bins. + template + struct static_storage_policy { + std::vector data_; + typedef T value_t; + typedef T variance_t; + std::size_t size() const { return data_.size(); } + void allocate(std::size_t n) { data_.resize(n, 0); } + void increase(std::size_t i) { ++data_.at(i); } + bool operator==(const static_storage_policy& other) const + { return data_ == other.data_; } + value_t value(std::size_t i) const { return data_.at(i); } + variance_t variance(std::size_t i) const { return data_.at(i); } + }; - It inherits from \ref boost::histogram::basic_histogram "basic_histogram", - which manages the stored axis - instances and the conversion of an n-dimensional tuple or index into an - internal linear offset that is used to address the bin count. How the bin - count is stored is an encapsulated implementation detail. - */ -class histogram : public basic_histogram { - BOOST_COPYABLE_AND_MOVABLE(histogram) -public: - histogram() {} + ///Use dynamic dimension + constexpr unsigned Dynamic = 0; - explicit histogram(const axes_type& axes); - -#define BOOST_HISTOGRAM_CTOR(z, n, unused) \ - explicit histogram( BOOST_PP_ENUM_PARAMS_Z(z, n, const axis_type& a) ) : \ - basic_histogram( BOOST_PP_ENUM_PARAMS_Z(z, n, a) ), \ - data_(field_count()) \ - {} - -// generates constructors taking 1 to AXIS_LIMIT arguments -BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_HISTOGRAM_AXIS_LIMIT), BOOST_HISTOGRAM_CTOR, nil) - -#if defined(BOOST_HISTOGRAM_DOXYGEN) - /**Constructors for a variable number of axis types, each defining the binning - scheme for its dimension. Up to \ref BOOST_HISTOGRAM_AXIS_LIMIT axis types - can be passed to the constructor, yielding the same number of dimensions. - - */ - explicit histogram(const axis_type& a0, ...); -#endif - // copy semantics (implementation needs to be here, workaround for gcc-bug) - histogram(const histogram& o) : - basic_histogram(o), - data_(o.data_) - {} - - histogram& operator=(BOOST_COPY_ASSIGN_REF(histogram) o) + template > + class histogram_t : private StoragePolicy { - if (this != &o) { - basic_histogram::operator=(static_cast(o)); - data_ = o.data_; + public: + using value_t = typename StoragePolicy::value_t; + using variance_t = typename StoragePolicy::variance_t; + + histogram_t() = default; + histogram_t(const histogram_t& other) = default; + histogram_t(histogram_t&& other) = default; + histogram_t& operator=(const histogram_t& other) = default; + histogram_t& operator=(histogram_t&& other) + { + if (this != &other) { + axes_ = std::move(other.axes_); + StoragePolicy::operator=(static_cast(other)); + } + return *this; } - return *this; - } - // move semantics (implementation needs to be here, workaround for gcc-bug) - histogram(BOOST_RV_REF(histogram) o) : - basic_histogram(::boost::move(static_cast(o))), - data_(::boost::move(o.data_)) - {} - - histogram& operator=(BOOST_RV_REF(histogram) o) - { - if (this != &o) { - basic_histogram::operator=(::boost::move(static_cast(o))); - data_ = ::boost::move(o.data_); + template + histogram_t(axis_t a, Axes... axes) + { + assign_axis(a, axes...); + StoragePolicy::allocate(field_count()); } - return *this; - } - /** Fills the histogram with a range. It checks at run-time - * that the size agrees with the dimensions of the histogram. + constexpr unsigned dim() const { return Dim; } - Allocation of internal memory is delayed until the first call to this function. - * - * \throws std::range_error If the range doesn't fit the dimension of the histogram. - */ - template - inline - typename boost::disable_if, void>::type - fill(Iterator begin, Iterator end) + std::size_t size() const { return StoragePolicy::size(); } + + // for convenience + std::size_t shape(unsigned i) const + { + BOOST_ASSERT(i < Dim); + return apply_visitor(visitor::shape(), axes_[i]); + } + + // for convenience + std::size_t bins(unsigned i) const + { + BOOST_ASSERT(i < Dim); + return apply_visitor(visitor::bins(), axes_[i]); + } + + template + void fill(Args... args) + { + static_assert(sizeof...(args) == Dim, + "number of arguments does not match histogram dimension"); + detail::linearize_x lin; + fill_impl(lin, std::forward(args)...); + StoragePolicy::increase(lin.out); + } + + template + value_t value(Args... args) + { + static_assert(sizeof...(args) == Dim, + "number of arguments does not match histogram dimension"); + detail::linearize lin; + index_impl(lin, std::forward(args)...); + return StoragePolicy::value(lin.out); + } + + template + variance_t variance(Args... args) + { + static_assert(sizeof...(args) == Dim, + "number of arguments does not match histogram dimension"); + detail::linearize lin; + index_impl(lin, std::forward(args)...); + return StoragePolicy::variance(lin.out); + } + + double sum() const + { + double result = 0.0; + for (std::size_t i = 0, n = size(); i < n; ++i) + result += StoragePolicy::value(i); + return result; + } + + template + bool operator==(const histogram_t& other) const + { + return dim() == other.dim() && axes_ == other.axes_ && + StoragePolicy::operator==(static_cast(other)); + } + + template + bool operator==(const histogram_t&) const + { return false; } + + private: + std::array axes_; + + std::size_t field_count() const + { + std::size_t fc = 1; + for (auto& a : axes_) + fc *= apply_visitor(visitor::shape(), a); + return fc; + } + + template + void assign_axis(First a, Rest... rest) + { + axes_[dim() - sizeof...(Rest) - 1] = a; + assign_axis(rest...); + } + void assign_axis() {} // stop recursion + + template + void fill_impl(detail::linearize_x& lin, First first, Rest... rest) + { + lin.in = first; + apply_visitor(lin, axes_[dim() - sizeof...(Rest) - 1]); + fill_impl(lin, rest...); + } + void fill_impl(detail::linearize_x&) {} // stop recursion + + template + void index_impl(detail::linearize& lin, First first, Rest... rest) + { + lin.in = first; + apply_visitor(lin, axes_[dim() - sizeof...(Rest) - 1]); + index_impl(lin, rest...); + } + void index_impl(detail::linearize&) {} // stop recursion + }; + + /// Type factory + template + histogram_t + histogram(Axes... axes) { - if(std::distance(begin, end) != dim()) - throw std::range_error("wrong number of arguments at fill"); - const size_type k = pos(begin, end); - if (k != uintmax_t(-1)) - data_.increase(k); + return histogram_t(std::forward(axes)...); } -#define BOOST_HISTOGRAM_FILL(z, n, unused) \ - inline \ - void fill( BOOST_PP_ENUM_PARAMS_Z(z, n, double x) ) \ - { \ - const double buffer[n] = { BOOST_PP_ENUM_PARAMS(n, x) }; \ - fill(boost::begin(buffer), boost::end(buffer)); \ - } - -// generates fill functions taking 1 to AXIS_LIMT arguments -BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_FILL, nil) - -#if defined(BOOST_HISTOGRAM_DOXYGEN) -/**\overload void fill(boost::iterator_range range) - Overload taking a variadic sequence. -*/ - void fill(double x0, ...); -#endif - - - /** Fills the histogram from a iterator range, - * using a weight. It checks at run-time that the length agrees with the - * dimensions of the histogram. - - Allocation of internal memory is delayed until the first call to this function. - If the histogram was filled with :cpp:func:`fill_c` before, the internal - memory is converted to the wide format used for storing weighted counts. - - If the data is not weighted (all weights are 1.0), using \ref fill is much - more space-efficient. In the most extreme case, storing of weighted counts - consumes 16x more memory. - * - * \throws std::range_error If the range doesn't fit the dimension of the histogram. - * - */ - template - inline - typename boost::disable_if, void>::type - wfill(Iterator begin, Iterator end, double w) - { - if (std::distance(begin, end) != dim()) - throw std::range_error("wrong number of arguments"); - const size_type k = pos(begin, end); - if (k != uintmax_t(-1)) - data_.increase(k, w); - } - -#define BOOST_HISTOGRAM_WFILL(z, n, unused) \ - inline \ - void wfill( BOOST_PP_ENUM_PARAMS_Z(z, n, double x), double w ) \ - { \ - const double buffer[n] = { BOOST_PP_ENUM_PARAMS(n, x) }; \ - wfill(boost::begin(buffer), boost::end(buffer), w); \ - } - -// generates wfill functions taking 1 to AXIS_LIMT arguments -BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_WFILL, nil) - - -#if defined(BOOST_HISTOGRAM_DOXYGEN) -/**\overload void wfill(boost::iterator_range range, double weight) - Overload taking a variadic sequence. -*/ - void fill(double x0, ...); -#endif - /** - * Returns the count of the bin addressed by the supplied index. - * Just like in Python, negative indices like ``-1`` are allowed and count - * from the end. So if an axis has ``k`` bins, ``-1`` points to ``k-1``. - * - * \throws std::range_error if the length does not match the dimension - */ - template - inline - typename boost::disable_if, double>::type - value(Iterator begin, Iterator end) const - { - if (std::distance(begin, end) != dim()) - throw std::range_error("wrong number of arguments"); - return data_.value(linearize(begin, end)); - } - -#define BOOST_HISTOGRAM_VALUE(z, n, unused) \ - inline \ - double value( BOOST_PP_ENUM_PARAMS_Z(z, n, int i) ) \ - const \ - { \ - const int idx[n] = { BOOST_PP_ENUM_PARAMS_Z(z, n, i) }; \ - return value(boost::begin(idx), boost::end(idx)); /* size is checked here */ \ - } - -// generates value functions taking 1 to AXIS_LIMT arguments -BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_VALUE, nil) - -#if defined(BOOST_HISTOGRAM_DOXYGEN) -/**\overload void value(boost::iterator_range range) - Overload taking a variadic sequence. -*/ - void value(double x0, ...); -#endif - -/** - * Returns the variance estimate for the count of the bin addressed by the supplied - * index. Negative indices are allowed just like in case of @ref histogram::value - * - * Note that it does not return the standard deviation :math:`\sigma`, commonly - * called "error", but the variance \f$\sigma^2\f$. - * - * In case of unweighted counts, the variance estimate returned is \f$n\f$, - * if the count is \f$n\f$. This is a common estimate for the variance based on - * the theory of the Poisson distribution. - * In case of weighted counts, the variance estimate returned is \f$\sum_i w_i^2\f$, - * if the individual weights are \f$w_i\f$. This estimate can be derived from - * the estimate above using uncertainty propagation. - * The extra storage needed for keeping track of the this sum is the reason why - * a histogram with weighted counts consumes more memory. - * - * \throws std::range_error if the length does not match the dimension - * - */ - template - inline - typename boost::disable_if, double>::type - variance(Iterator begin, Iterator end) const - { - if (std::distance(begin, end) != dim()) - throw std::runtime_error("wrong number of arguments"); - return data_.variance(linearize(begin, end)); - } - -#define BOOST_HISTOGRAM_VARIANCE(z, n, unused) \ - inline \ - double variance( BOOST_PP_ENUM_PARAMS_Z(z, n, int i) ) \ - const \ - { \ - const int idx[n] = { BOOST_PP_ENUM_PARAMS_Z(z, n, i) }; \ - return variance(boost::begin(idx), boost::end(idx)); /* size is checked here */ \ - } - -// generates variance functions taking 1 to AXIS_LIMT arguments -BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_HISTOGRAM_VARIANCE, nil) - -#if defined(BOOST_HISTOGRAM_DOXYGEN) -/**\overload void variance(boost::iterator_range range) - Overload taking a variadic sequence. -*/ - void variance(double x0, ...); -#endif - - ///Returns the current size of a count in the internal memory buffer in number of bytes. - unsigned depth() const { return data_.depth(); } - - ///Returns the sum of bin counts, including overflow and underflow bins. This could be implemented as a free function. - double sum() const; - - ///Returns true if the two histograms have the dimension, same axis types, and same data content. Two otherwise identical histograms are not considered equal, if they do not have the same depth, even if counts and variances are the same. This case only occurs if one histogram is filled using :cpp:func:`fill` and the other with :cpp:func:`wfill`, using weights of 1. - bool operator==(const histogram& o) const - { return basic_histogram::operator==(o) && - data_ == o.data_; } - - ///Adds the counts of the histogram on the right hand side to this histogram, if the two histograms have the same signature. Otherwise, a :cpp:type:`std::logic_error` is thrown. Returns itself. - histogram& operator+=(const histogram& o) - { - if (!basic_histogram::operator==(o)) - throw std::logic_error("histograms have different axes"); - data_ += o.data_; - return *this; - } - - const void* buffer() const {return data_.buffer();}; -private: - detail::nstore data_; - - template - friend void serialize(Archive& ar, histogram & h, unsigned version); -}; - -inline histogram operator+(const histogram& a, const histogram& b) { - histogram result(a); - return result += b; -} - } } diff --git a/include/boost/histogram/serialization.hpp b/include/boost/histogram/serialization.hpp deleted file mode 100644 index 781e4e1c..00000000 --- a/include/boost/histogram/serialization.hpp +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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_HISTOGRAM_SERIALIZATION_HPP_ -#define BOOST_HISTOGRAM_SERIALIZATION_HPP_ - -#include -#include -#include -#include -#include - - -/** \file boost/histogram/serialization.hpp - * \brief Defines the serialization functions, to use with boost.serialize. - * - */ - -namespace boost { -namespace histogram { - -namespace detail { - -template -inline void serialize_save_impl(Archive & ar, const nstore & store, unsigned version) -{ - std::vector buf; - if (zero_suppression_encode(buf, static_cast(store.buffer_), store.size_)) { - bool is_zero_suppressed = true; - ar & is_zero_suppressed; - ar & buf; - } else { - bool is_zero_suppressed = false; - ar & is_zero_suppressed; - ar & serialization::make_array(static_cast(store.buffer_), store.size_); - } -} - -template -inline void serialize_load_impl(Archive & ar, nstore & store, - bool is_zero_suppressed, unsigned version) -{ - if (is_zero_suppressed) { - std::vector buf; - ar & buf; - zero_suppression_decode(static_cast(store.buffer_), store.size_, buf); - } else { - ar & serialization::make_array(static_cast(store.buffer_), store.size_); - } -} - -template -inline void serialize(Archive& ar, nstore & store, unsigned version) -{ - const nstore::size_type s = store.size_; - const unsigned d = store.depth_; - ar & store.size_; - ar & store.depth_; - if (s != store.size_ || d != store.depth_) { - // realloc is safe if buffer_ is null - store.buffer_ = std::realloc(store.buffer_, store.size_ * store.depth_); - } - if (store.buffer_ == 0 && store.size_ > 0) - throw std::bad_alloc(); - - if (Archive::is_saving::value) { - switch (store.depth_) { - case nstore::d1: serialize_save_impl (ar, store, version); break; - case nstore::d2: serialize_save_impl(ar, store, version); break; - case nstore::d4: serialize_save_impl(ar, store, version); break; - case nstore::d8: serialize_save_impl(ar, store, version); break; - case nstore::dw: serialize_save_impl (ar, store, version); break; - } - } - - if (Archive::is_loading::value) { - bool is_zero_suppressed = false; - ar & is_zero_suppressed; - switch (store.depth_) { - case nstore::d1 : serialize_load_impl (ar, store, is_zero_suppressed, version); break; - case nstore::d2 : serialize_load_impl(ar, store, is_zero_suppressed, version); break; - case nstore::d4 : serialize_load_impl(ar, store, is_zero_suppressed, version); break; - case nstore::d8 : serialize_load_impl(ar, store, is_zero_suppressed, version); break; - case nstore::dw : serialize_load_impl (ar, store, is_zero_suppressed, version); break; - } - } -} - -template -inline void serialize(Archive& ar, wtype & wt, unsigned version) -{ - ar & wt.w; ar & wt.w2; -} - -} // ns:detail - -template -inline void serialize(Archive& ar, axis_base & base, unsigned version) -{ - ar & base.size_; - ar & base.label_; -} - -template -inline void serialize(Archive& ar, regular_axis & axis ,unsigned version) -{ - ar & boost::serialization::base_object(axis); - ar & axis.min_; - ar & axis.range_; -} - -template -inline void serialize(Archive& ar, polar_axis & axis, unsigned version) -{ - ar & boost::serialization::base_object(axis); - ar & axis.start_; -} - -template -inline void serialize(Archive& ar, variable_axis & axis, unsigned version) -{ - ar & boost::serialization::base_object(axis); - if (Archive::is_loading::value) - axis.x_.reset(new double[axis.bins() + 1]); - ar & boost::serialization::make_array(axis.x_.get(), axis.bins() + 1); -} - -template -inline void serialize(Archive& ar, category_axis & axis, unsigned version) -{ - ar & axis.categories_; -} - -template -inline void serialize(Archive& ar, integer_axis & axis, unsigned version) -{ - ar & boost::serialization::base_object(axis); - ar & axis.min_; -} - -template -inline void serialize(Archive& ar, basic_histogram & h, unsigned version) -{ - unsigned size = h.axes_.size(); - ar & size; - if (Archive::is_loading::value) - h.axes_.resize(size); - ar & boost::serialization::make_array(&h.axes_[0], size); -} - -template -inline void serialize(Archive& ar, histogram & h, unsigned version) -{ - ar & boost::serialization::base_object(h); - ar & h.data_; -} - -} // ns:histogram -} // ns:boost - -#endif diff --git a/src/axis.cpp b/src/axis.cpp index ee12e04d..7160ca1e 100644 --- a/src/axis.cpp +++ b/src/axis.cpp @@ -182,18 +182,7 @@ variable_axis::operator==(const variable_axis& o) const return true; } -category_axis::category_axis(const std::string& s) -{ - std::size_t i = s.find(';'); - categories_.push_back(s.substr(0, i)); - while (i != std::string::npos) { - const std::size_t p = i + 1; - i = s.find(';', p); - categories_.push_back(s.substr(p, i - p)); - } -} - -category_axis::category_axis(const std::vector& c) : +category_axis::category_axis(const std::initializer_list& c) : categories_(c) {} diff --git a/src/basic_histogram.cpp b/src/basic_histogram.cpp deleted file mode 100644 index af2733b3..00000000 --- a/src/basic_histogram.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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 -#include -#include - -namespace boost { -namespace histogram { - -basic_histogram::basic_histogram(const axes_type& axes) : - axes_(axes) -{ - if (axes_.size() > BOOST_HISTOGRAM_AXIS_LIMIT) - throw std::invalid_argument("too many axes"); -} - -bool -basic_histogram::operator==(const basic_histogram& o) - const -{ - if (axes_.size() != o.axes_.size()) - return false; - for (unsigned i = 0; i < axes_.size(); ++i) { - if (!apply_visitor(visitor::cmp(), axes_[i], o.axes_[i])) - return false; - } - return true; -} - -basic_histogram::size_type -basic_histogram::field_count() - const -{ - if (axes_.empty()) - return 0; - size_type fc = 1; - for (unsigned i = 0, n = axes_.size(); i < n; ++i) - fc *= shape(i); - return fc; -} - -} -} diff --git a/src/histogram.cpp b/src/histogram.cpp deleted file mode 100644 index 14e41d74..00000000 --- a/src/histogram.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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 -#include - -namespace boost { -namespace histogram { - -histogram::histogram(const axes_type& axes) : - basic_histogram(axes), - data_(field_count()) -{} - -double -histogram::sum() - const -{ - double result = 0.0; - for (size_type i = 0, n = field_count(); i < n; ++i) - result += data_.value(i); - return result; -} - -} -} diff --git a/src/python/axis.cpp b/src/python/axis.cpp deleted file mode 100644 index 95ce613b..00000000 --- a/src/python/axis.cpp +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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 -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace histogram { - -namespace { - -python::object -variable_axis_init(python::tuple args, python::dict kwargs) { - using namespace python; - using python::tuple; - - object self = args[0]; - object pyinit = self.attr("__init__"); - - if (len(args) < 2) { - PyErr_SetString(PyExc_TypeError, "require at least two arguments"); - throw_error_already_set(); - } - - std::vector v; - for (int i = 1, n = len(args); i < n; ++i) { - v.push_back(extract(args[i])); - } - - std::string label; - bool uoflow = true; - while (len(kwargs) > 0) { - tuple kv = kwargs.popitem(); - std::string k = extract(kv[0]); - object v = kv[1]; - if (k == "label") - label = extract(v); - else if (k == "uoflow") - uoflow = extract(v); - else { - std::stringstream s; - s << "keyword " << k << " not recognized"; - PyErr_SetString(PyExc_KeyError, s.str().c_str()); - throw_error_already_set(); - } - } - return pyinit(v, label, uoflow); -} - -python::object -category_axis_init(python::tuple args, python::dict kwargs) { - using namespace python; - - object self = args[0]; - object pyinit = self.attr("__init__"); - - if (len(args) == 1) { - PyErr_SetString(PyExc_TypeError, "require at least one argument"); - throw_error_already_set(); - } - - if (len(kwargs) > 0) { - PyErr_SetString(PyExc_TypeError, "unknown keyword argument"); - throw_error_already_set(); - } - - if (len(args) == 2) { - extract es(args[1]); - if (es.check()) - pyinit(es); - else { - PyErr_SetString(PyExc_TypeError, "require one or several string arguments"); - throw_error_already_set(); - } - } - - std::vector c; - for (int i = 1, n = len(args); i < n; ++i) - c.push_back(extract(args[i])); - - return pyinit(c); -} - -template -int -axis_len(const T& t) { - return t.bins() + 1; -} - -template <> -int -axis_len(const category_axis& t) { - return t.bins(); -} - -template <> -int -axis_len(const integer_axis& t) { - return t.bins(); -} - -template -typename T::value_type -axis_getitem(const T& t, int i) { - if (i == axis_len(t)) { - PyErr_SetString(PyExc_StopIteration, "no more"); - python::throw_error_already_set(); - } - return t[i]; -} - -template -std::string -axis_repr(const T& t) { - std::ostringstream os; - os << t; - return os.str(); -} - -template -struct has_index_method -{ - struct yes { char x[1]; }; - struct no { char x[2]; }; - template struct SFINAE {}; - template static yes test( SFINAE* ); - template static no test( ... ); - enum { value = sizeof(test(0)) == sizeof(yes) }; -}; - -template -struct axis_suite : public python::def_visitor > { - - template - static - typename enable_if_c::value, void>::type - add_axis_index(Class& cl) { - cl.def("index", &U::index, - ":param float x: value" - "\n:returns: bin index for the passed value", - python::args("self", "x")); - } - - template - static - typename disable_if_c::value, void>::type - add_axis_index(Class& cl) {} - - template - static - typename enable_if, void>::type - add_axis_label(Class& cl) { - cl.add_property("label", - python::make_function((const std::string&(U::*)() const) &U::label, - python::return_value_policy()), - (void(U::*)(const std::string&)) &U::label, - "Name or description for the axis."); - } - - template - static - typename disable_if, void>::type - add_axis_label(Class& cl) {} - - template - static void - visit(Class& cl) - { - cl.add_property("bins", &T::bins); - add_axis_index(cl); - add_axis_label(cl); - cl.def("__len__", axis_len, - ":returns: number of bins for this axis", - python::arg("self")); - cl.def("__getitem__", axis_getitem, - is_same::value ? - ":returns: integer mapped to passed bin index" : - is_same::value ? - ":returns: category mapped to passed bin index" : - ":returns: low edge of the bin", - python::args("self", "index")); - cl.def("__repr__", axis_repr, - ":returns: string representation of this axis", - python::arg("self")); - cl.def(python::self == python::self); - } -}; - -} // namespace - -void register_axis_types() -{ - using namespace python; - using python::arg; - docstring_options dopt(true, true, false); - - // used to pass arguments from raw python init to specialized C++ constructors - class_ >("vector_double", no_init); - class_ >("vector_string", no_init); - - class_("regular_axis", - "An axis for real-valued data and bins of equal width." - "\nBinning is a O(1) operation.", - no_init) - .def(init( - (arg("self"), arg("bin"), arg("min"), arg("max"), - arg("label") = std::string(), - arg("uoflow") = true))) - .def(axis_suite()) - ; - - class_("polar_axis", - "An axis for real-valued angles." - "\nThere are no overflow/underflow bins for this axis," - "\nsince the axis is circular and wraps around after 2pi." - "\nBinning is a O(1) operation.", - no_init) - .def(init( - (arg("self"), arg("bin"), arg("start") = 0.0, - arg("label") = std::string()))) - .def(axis_suite()) - ; - - class_("variable_axis", - "An axis for real-valued data and bins of varying width." - "\nBinning is a O(log(N)) operation. If speed matters and" - "\nthe problem domain allows it, prefer a regular_axis.", - no_init) - .def("__init__", raw_function(variable_axis_init)) - .def(init, std::string, bool>()) - .def(axis_suite()) - ; - - class_("category_axis", - "An axis for enumerated categories. The axis stores the" - "\ncategory labels, and expects that they are addressed" - "\nusing an integer from 0 to n-1. There are no" - "\nunderflow/overflow bins for this axis." - "\nBinning is a O(1) operation.", - no_init) - .def("__init__", raw_function(category_axis_init)) - .def(init()) - .def(init >()) - .def(axis_suite()) - ; - - class_("integer_axis", - "An axis for a contiguous range of integers." - "\nThere are no underflow/overflow bins for this axis." - "\nBinning is a O(1) operation.", - no_init) - .def(init( - (arg("self"), arg("min"), arg("max"), - arg("label") = std::string(), - arg("uoflow") = true))) - .def(axis_suite()) - ; -} - -} -} diff --git a/src/python/basic_histogram.cpp b/src/python/basic_histogram.cpp deleted file mode 100644 index 3bdd6d3b..00000000 --- a/src/python/basic_histogram.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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 -#include -#include -#include - -namespace boost { -namespace histogram { - -namespace { - -struct axis_visitor : public static_visitor -{ - template - python::object operator()(const T& t) const { return python::object(T(t)); } -}; - -python::object -basic_histogram_axis(const basic_histogram& self, unsigned i) -{ - return apply_visitor(axis_visitor(), self.axis(i)); -} - -} // namespace - -void register_basic_histogram() { - using namespace python; - using python::arg; - docstring_options dopt(true, true, false); - - class_("basic_histogram", no_init) - .add_property("dim", &basic_histogram::dim, - "dimensions of the histogram") - .def("shape", &basic_histogram::shape, - ":param int i: index of the axis\n" - ":returns: number of count fields for axis i\n" - " (bins + 2 if underflow and overflow" - " bins are enabled, otherwise equal to bins", - args("self", "i")) - .def("axis", basic_histogram_axis, - ":param int i: index of the axis\n" - ":returns: axis object for axis i", - args("self", "i")) - ; -} - -} -} diff --git a/src/python/histogram.cpp b/src/python/histogram.cpp deleted file mode 100644 index d8a75615..00000000 --- a/src/python/histogram.cpp +++ /dev/null @@ -1,282 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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 "serialization_suite.hpp" -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_NUMPY -# define NO_IMPORT_ARRAY -# define PY_ARRAY_UNIQUE_SYMBOL boost_histogram_ARRAY_API -# define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION -# include -#endif - -namespace boost { -namespace histogram { - -python::object -histogram_init(python::tuple args, python::dict kwargs) { - using namespace python; - using python::tuple; - - object self = args[0]; - object pyinit = self.attr("__init__"); - - if (kwargs) { - PyErr_SetString(PyExc_RuntimeError, "no keyword arguments allowed"); - throw_error_already_set(); - } - - // normal constructor - basic_histogram::axes_type axes; - for (unsigned i = 1, n = len(args); i < n; ++i) { - object pa = args[i]; - extract er(pa); - if (er.check()) { axes.push_back(er()); continue; } - extract ep(pa); - if (ep.check()) { axes.push_back(ep()); continue; } - extract ev(pa); - if (ev.check()) { axes.push_back(ev()); continue; } - extract ec(pa); - if (ec.check()) { axes.push_back(ec()); continue; } - extract ei(pa); - if (ei.check()) { axes.push_back(ei()); continue; } - PyErr_SetString(PyExc_TypeError, "require an axis object"); - throw_error_already_set(); - } - return pyinit(axes); -} - -python::object -histogram_fill(python::tuple args, python::dict kwargs) { - using namespace python; - - const unsigned nargs = len(args); - histogram& self = extract(args[0]); - - object ow; - if (kwargs) { - if (len(kwargs) > 1 || !kwargs.has_key("w")) { - PyErr_SetString(PyExc_RuntimeError, "only keyword w allowed"); - throw_error_already_set(); - } - ow = kwargs.get("w"); - } - -#ifdef HAVE_NUMPY - if (nargs == 2) { - object o = args[1]; - if (PySequence_Check(o.ptr())) { - PyArrayObject* a = reinterpret_cast - (PyArray_FROM_OTF(o.ptr(), NPY_DOUBLE, NPY_ARRAY_IN_ARRAY)); - if (!a) { - PyErr_SetString(PyExc_ValueError, "could not convert sequence into array"); - throw_error_already_set(); - } - - npy_intp* dims = PyArray_DIMS(a); - switch (PyArray_NDIM(a)) { - case 1: - if (self.dim() > 1) { - PyErr_SetString(PyExc_ValueError, "array has to be two-dimensional"); - throw_error_already_set(); - } - break; - case 2: - if (self.dim() != dims[1]) - { - PyErr_SetString(PyExc_ValueError, "size of second dimension does not match"); - throw_error_already_set(); - } - break; - default: - PyErr_SetString(PyExc_ValueError, "array has wrong dimension"); - throw_error_already_set(); - } - - if (!ow.is_none()) { - if (PySequence_Check(ow.ptr())) { - PyArrayObject* aw = reinterpret_cast - (PyArray_FROM_OTF(ow.ptr(), NPY_DOUBLE, NPY_ARRAY_IN_ARRAY)); - if (!aw) { - PyErr_SetString(PyExc_ValueError, "could not convert sequence into array"); - throw_error_already_set(); - } - - if (PyArray_NDIM(aw) != 1) { - PyErr_SetString(PyExc_ValueError, "array has to be one-dimensional"); - throw_error_already_set(); - } - - if (PyArray_DIMS(aw)[0] != dims[0]) { - PyErr_SetString(PyExc_ValueError, "sizes do not match"); - throw_error_already_set(); - } - - for (unsigned i = 0; i < dims[0]; ++i) { - double* v = reinterpret_cast(PyArray_GETPTR1(a, i) ); - double* w = reinterpret_cast(PyArray_GETPTR1(aw, i)); - self.wfill(v, v+self.dim(), *w); - } - - Py_DECREF(aw); - } else { - PyErr_SetString(PyExc_ValueError, "w is not a sequence"); - throw_error_already_set(); - } - } else { - for (unsigned i = 0; i < dims[0]; ++i) { - double* v = reinterpret_cast(PyArray_GETPTR1(a, i)); - self.fill(v, v+self.dim()); - } - } - - Py_DECREF(a); - return object(); - } - } -#endif - - const unsigned dim = nargs - 1; - if (dim != self.dim()) { - PyErr_SetString(PyExc_RuntimeError, "wrong number of arguments"); - throw_error_already_set(); - } - - double v[BOOST_HISTOGRAM_AXIS_LIMIT]; - for (unsigned i = 0; i < dim; ++i) - v[i] = extract(args[1 + i]); - - if (ow.is_none()) { - self.fill(v, v+self.dim()); - - } else { - const double w = extract(ow); - self.wfill(v, v+self.dim(), w); - } - - return object(); -} - -python::object -histogram_value(python::tuple args, python::dict kwargs) { - using namespace python; - const histogram& self = extract(args[0]); - - if (self.dim() != (len(args) - 1)) { - PyErr_SetString(PyExc_RuntimeError, "wrong number of arguments"); - throw_error_already_set(); - } - - if (kwargs) { - PyErr_SetString(PyExc_ValueError, "no keyword arguments allowed"); - throw_error_already_set(); - } - - int idx[BOOST_HISTOGRAM_AXIS_LIMIT]; - for (unsigned i = 0; i < self.dim(); ++i) - idx[i] = extract(args[1 + i]); - - return object(self.value(idx, idx + self.dim())); -} - -python::object -histogram_variance(python::tuple args, python::dict kwargs) { - using namespace python; - const histogram& self = extract(args[0]); - - if (self.dim() != (len(args) - 1)) { - PyErr_SetString(PyExc_RuntimeError, "wrong number of arguments"); - throw_error_already_set(); - } - - if (kwargs) { - PyErr_SetString(PyExc_RuntimeError, "no keyword arguments allowed"); - throw_error_already_set(); - } - - int idx[BOOST_HISTOGRAM_AXIS_LIMIT]; - for (unsigned i = 0; i < self.dim(); ++i) - idx[i] = extract(args[1 + i]); - - return object(self.variance(idx, idx + self.dim())); -} - -class histogram_access { -public: - static - python::dict - histogram_array_interface(histogram& self) { - python::dict d; - python::list shape; - for (unsigned i = 0; i < self.dim(); ++i) - shape.append(self.shape(i)); - if (self.depth() == sizeof(detail::wtype)) { - shape.append(2); - d["typestr"] = python::str("(self.buffer()), false); - return d; - } -}; - -void register_histogram() -{ - using namespace python; - docstring_options dopt(true, true, false); - - // used to pass arguments from raw python init to specialized C++ constructor - class_("axes", no_init); - - class_< - histogram, bases, - shared_ptr - >("histogram", - "N-dimensional histogram for real-valued data.", - no_init) - .def("__init__", raw_function(histogram_init), - ":param axis args: axis objects" - "\nPass one or more axis objects to define" - "\nthe dimensions of the histogram.") - // shadowed C++ ctors - .def(init()) - .add_property("__array_interface__", - &histogram_access::histogram_array_interface) - .def("fill", raw_function(histogram_fill), - "Pass a sequence of values with a length n is" - "\nequal to the dimensions of the histogram," - "\nand optionally a weight w for this fill" - "\n(*int* or *float*)." - "\n" - "\nIf Numpy support is enabled, values may also" - "\nbe a 2d-array of shape (m, n), where m is" - "\nthe number of tuples, and optionally" - "\nanother a second 1d-array w of shape (n,).") - .add_property("depth", &histogram::depth) - .add_property("sum", &histogram::sum) - .def("value", raw_function(histogram_value), - ":param int args: indices of the bin" - "\n:return: count for the bin") - .def("variance", raw_function(histogram_variance), - ":param int args: indices of the bin" - "\n:return: variance estimate for the bin") - .def(self == self) - .def(self += self) - .def(self + self) - .def_pickle(serialization_suite()) - ; -} - -} -} diff --git a/src/python/module.cpp b/src/python/module.cpp deleted file mode 100644 index 703b5dbf..00000000 --- a/src/python/module.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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 -#ifdef HAVE_NUMPY -# define PY_ARRAY_UNIQUE_SYMBOL boost_histogram_ARRAY_API -# define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION -# include -# if PY_MAJOR_VERSION >= 3 -static void* init_numpy() { import_array(); return NULL; } -# else -static void init_numpy() { import_array(); } -# endif -#endif - -namespace boost { -namespace histogram { - void register_axis_types(); - void register_basic_histogram(); - void register_histogram(); -} -} - -BOOST_PYTHON_MODULE(histogram) -{ -#ifdef HAVE_NUMPY - init_numpy(); -#endif - boost::histogram::register_axis_types(); - boost::histogram::register_basic_histogram(); - boost::histogram::register_histogram(); -} diff --git a/src/python/serialization_suite.hpp b/src/python/serialization_suite.hpp deleted file mode 100644 index 6f52b0d1..00000000 --- a/src/python/serialization_suite.hpp +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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_PYTHON_SERIALIZATION_SUITE_HPP_ -#define _BOOST_PYTHON_SERIALIZATION_SUITE_HPP_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace boost { -namespace histogram { -namespace detail { - -#if PY_MAJOR_VERSION < 3 -# define PyBytes_FromStringAndSize PyString_FromStringAndSize -# define PyBytes_AS_STRING PyString_AS_STRING -# define PyBytes_Size PyString_Size -# define _PyBytes_Resize _PyString_Resize -#endif - -class python_bytes_sink : public iostreams::sink { -public: - python_bytes_sink(PyObject** pstr) : - pstr_(pstr), - len_(0), - pos_(0) - { BOOST_ASSERT(*pstr == 0); } - - std::streamsize write(const char* s, std::streamsize n) - { - if (len_ == 0) { - *pstr_ = PyBytes_FromStringAndSize(s, n); - if (*pstr_ == 0) { - PyErr_SetString(PyExc_RuntimeError, "cannot allocate memory"); - python::throw_error_already_set(); - } - len_ = n; - } else { - if (pos_ + n > len_) { - len_ = pos_ + n; - if (_PyBytes_Resize(pstr_, len_) == -1) - python::throw_error_already_set(); - } - char* b = PyBytes_AS_STRING(*pstr_); - std::copy(s, s + n, b + pos_); - } - pos_ += n; - return n; - } - -private: - PyObject** pstr_; - std::streamsize len_, pos_; -}; - -} - -template -struct serialization_suite : python::pickle_suite -{ - static - python::tuple getstate(python::object obj) - { - PyObject* pobj = 0; - iostreams::stream os(&pobj); - archive::text_oarchive oa(os); - oa << python::extract(obj)(); - os.flush(); - return python::make_tuple(obj.attr("__dict__"), - python::object(python::handle<>(pobj))); - } - - static - void setstate(python::object obj, python::tuple state) - { - if (python::len(state) != 2) { - PyErr_SetObject(PyExc_ValueError, - ("expected 2-item tuple in call to __setstate__; got %s" - % state).ptr()); - python::throw_error_already_set(); - } - - // restore the object's __dict__ - python::dict d = python::extract(obj.attr("__dict__")); - d.update(state[0]); - - // restore the C++ object - python::object o = state[1]; - iostreams::stream - is(PyBytes_AS_STRING(o.ptr()), PyBytes_Size(o.ptr())); - archive::text_iarchive ia(is); - ia >> python::extract(obj)(); - } - - static - bool getstate_manages_dict() { return true; } -}; - -#undef PyBytes_FromStringAndSize -#undef PyBytes_AS_STRING -#undef PyBytes_Size -#undef _PyBytes_Resize - -} -} - -#endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 deleted file mode 100644 index 84c79a89..00000000 --- a/test/Jamfile.v2 +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright Klemens David Morgenstern 2016. 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) - - - -#use-project /boost/histogram : ../build ; - -project - : requirements - windows:WIN32_LEAN_AND_MEAN - linux:-lpthread - ; - - -import testing ; -import python ; -import os ; - -test-suite ts : - [ compile check/sizeof.cpp ] - [ compile serialization.cpp ] - #[ compile check/speed_vs_root.cpp ] //not in yet, cause it needs an external library - [ run axis_test.cpp /boost//histogram /boost//test_exec_monitor : BOOST_TEST_DYN_LINK=1 ] - [ run histogram_test.cpp /boost//histogram /boost//test_exec_monitor : BOOST_TEST_DYN_LINK=1 ] - [ run nstore_test.cpp /boost//histogram /boost//test_exec_monitor : BOOST_TEST_DYN_LINK=1 ] - [ run zero_suppression_test.cpp /boost//histogram /boost//test_exec_monitor : BOOST_TEST_DYN_LINK=1 ] - ; - - diff --git a/test/axis_test.cpp b/test/axis_test.cpp index bb6bf071..033dfd83 100644 --- a/test/axis_test.cpp +++ b/test/axis_test.cpp @@ -4,22 +4,19 @@ // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) -#include #define BOOST_TEST_MODULE axis_test +#include #include #include -#include #include -#include #include #include -using namespace boost::assign; using namespace boost::histogram; // only test things not already covered by python_test_suite BOOST_AUTO_TEST_CASE(regular_axis_operators) { - regular_axis a(3, -1, 1); + regular_axis a{3, -1, 1}; BOOST_CHECK_EQUAL(a[-1], -std::numeric_limits::infinity()); BOOST_CHECK_EQUAL(a[a.bins() + 1], std::numeric_limits::infinity()); regular_axis b; @@ -32,7 +29,7 @@ BOOST_AUTO_TEST_CASE(regular_axis_operators) { BOOST_AUTO_TEST_CASE(polar_axis_operators) { using namespace boost::math::double_constants; - polar_axis a(4); + polar_axis a{4}; BOOST_CHECK_EQUAL(a[-1], a[a.bins() - 1] - two_pi); polar_axis b; BOOST_CHECK_NE(a, b); @@ -43,9 +40,7 @@ BOOST_AUTO_TEST_CASE(polar_axis_operators) { } BOOST_AUTO_TEST_CASE(variable_axis_operators) { - std::vector x; - x += -1, 0, 1; - variable_axis a(x); + variable_axis a{-1, 0, 1}; BOOST_CHECK_EQUAL(a[-1], -std::numeric_limits::infinity()); BOOST_CHECK_EQUAL(a[a.bins() + 1], std::numeric_limits::infinity()); variable_axis b; @@ -57,7 +52,7 @@ BOOST_AUTO_TEST_CASE(variable_axis_operators) { } BOOST_AUTO_TEST_CASE(category_axis_operators) { - category_axis a("A;B;C"); + category_axis a{"A", "B", "C"}; category_axis b; BOOST_CHECK_NE(a, b); b = a; @@ -67,7 +62,7 @@ BOOST_AUTO_TEST_CASE(category_axis_operators) { } BOOST_AUTO_TEST_CASE(integer_axis_operators) { - integer_axis a(-1, 1); + integer_axis a{-1, 1}; integer_axis b; BOOST_CHECK_NE(a, b); b = a; @@ -76,17 +71,30 @@ BOOST_AUTO_TEST_CASE(integer_axis_operators) { BOOST_CHECK_EQUAL(a, b); } -BOOST_AUTO_TEST_CASE(axis_type_streamable) { - std::vector x; - x += -1, 0, 1; - std::vector axes; - axes.push_back(regular_axis(2, -1, 1)); - axes.push_back(polar_axis(4)); - axes.push_back(variable_axis(x)); - axes.push_back(category_axis("A;B;C")); - axes.push_back(integer_axis(-1, 1)); +BOOST_AUTO_TEST_CASE(axis_t_streamable) { + std::vector axes; + axes.push_back(regular_axis{2, -1, 1}); + axes.push_back(polar_axis{4}); + axes.push_back(variable_axis{-1, 0, 1}); + axes.push_back(category_axis{"A", "B", "C"}); + axes.push_back(integer_axis{-1, 1}); std::ostringstream os; - BOOST_FOREACH(const axis_type& a, axes) + for(const auto& a : axes) os << a; BOOST_CHECK(!os.str().empty()); } + +BOOST_AUTO_TEST_CASE(axis_t_equal_comparable) { + std::vector axes; + axes.push_back(regular_axis{2, -1, 1}); + axes.push_back(polar_axis{4}); + axes.push_back(variable_axis{-1, 0, 1}); + axes.push_back(category_axis{"A", "B", "C"}); + axes.push_back(integer_axis{-1, 1}); + for (const auto& a : axes) { + BOOST_CHECK(!(a == axis_t())); + BOOST_CHECK_EQUAL(a, a); + } + BOOST_CHECK(!(axes == std::vector())); + BOOST_CHECK(axes == std::vector(axes)); +} diff --git a/test/check/sizeof.cpp b/test/check/sizeof.cpp deleted file mode 100644 index 8e1f0cc1..00000000 --- a/test/check/sizeof.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -int main(int argc, char** argv) { - using namespace boost::histogram; - #define SIZEOF(x) std::printf("%32s: %lu\n", BOOST_STRINGIZE(x), sizeof(x)) - SIZEOF(char); - SIZEOF(int); - SIZEOF(long); - SIZEOF(float); - SIZEOF(double); - SIZEOF(void*); - SIZEOF(detail::wtype); - SIZEOF(boost::multiprecision::int128_t); - SIZEOF(boost::multiprecision::int512_t); - SIZEOF(boost::multiprecision::cpp_int); - SIZEOF(std::string); - SIZEOF(std::vector); - SIZEOF(std::valarray); - SIZEOF(boost::container::vector); - typedef boost::container::static_vector static_vector_a16; - SIZEOF(static_vector_a16); - SIZEOF(boost::scoped_array); - SIZEOF(regular_axis); - SIZEOF(polar_axis); - SIZEOF(variable_axis); - SIZEOF(category_axis); - SIZEOF(integer_axis); - SIZEOF(axis_type); -} diff --git a/test/check/speed_cpp.cpp b/test/check/speed_cpp.cpp new file mode 100644 index 00000000..6edb2fe4 --- /dev/null +++ b/test/check/speed_cpp.cpp @@ -0,0 +1,122 @@ +// Copyright 2015-2016 Hans Dembinski +// +// 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 +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace std; +using namespace boost::histogram; + +template +struct rng { + boost::random::mt19937 r; + D d; + rng(double a, double b) : d(a, b) {} + double operator()() { return d(r); } +}; + +vector random_array(unsigned n, int type) { + using namespace boost::random; + std::vector result; + switch (type) { + case 0: + std::generate_n(std::back_inserter(result), n, rng >(0.0, 1.0)); + break; + case 1: + std::generate_n(std::back_inserter(result), n, rng >(0.0, 0.3)); + break; + } + return result; +} + +void compare_1d(unsigned n, int distrib) +{ + vector r = random_array(n, distrib); + + double best_boost = std::numeric_limits::max(); + for (unsigned k = 0; k < 10; ++k) { + histogram h(regular_axis(100, 0, 1)); + t = clock(); + for (unsigned i = 0; i < n; ++i) + h.fill(r[i]); + t = clock() - t; + best_boost = std::min(best_boost, double(t) / CLOCKS_PER_SEC); + // printf("root %g this %g\n", hroot.GetSum(), h.sum()); + assert(hroot.GetSum() == h.sum()); + } + + printf("1D\n"); + printf("t[boost] = %.3f\n", best_boost); +} + +void compare_3d(unsigned n, int distrib) +{ + vector r = random_array(3 * n, distrib); + + double best_boost = std::numeric_limits::max(); + for (unsigned k = 0; k < 10; ++k) { + histogram h(regular_axis(100, 0, 1), + regular_axis(100, 0, 1), + regular_axis(100, 0, 1)); + t = clock(); + for (unsigned i = 0; i < n; ++i) + h.fill(r[3 * i], r[3 * i + 1], r[3 * i + 2]); + t = clock() - t; + best_boost = std::min(best_boost, double(t) / CLOCKS_PER_SEC); + assert(hroot.GetSum() == h.sum()); + } + + printf("3D\n"); + printf("t[boost] = %.3f\n", best_boost); +} + +void compare_6d(unsigned n, int distrib) +{ + vector r = random_array(6 * n, distrib); + + double best_boost = std::numeric_limits::max(); + for (unsigned k = 0; k < 10; ++k) { + double x[6]; + + histogram h(regular_axis(10, 0, 1), + regular_axis(10, 0, 1), + regular_axis(10, 0, 1), + regular_axis(10, 0, 1), + regular_axis(10, 0, 1), + regular_axis(10, 0, 1)); + + t = clock(); + for (unsigned i = 0; i < n; ++i) { + for (unsigned k = 0; k < 6; ++k) + x[k] = r[6 * i + k]; + h.fill(x, x+6); + } + t = clock() - t; + best_boost = std::min(best_boost, double(t) / CLOCKS_PER_SEC); + } + + printf("6D\n"); + printf("t[boost] = %.3f\n", best_boost); +} + +int main() { + printf("uniform distribution\n"); + compare_1d(12000000, 0); + compare_3d(4000000, 0); + compare_6d(2000000, 0); + printf("normal distribution\n"); + compare_1d(12000000, 1); + compare_3d(4000000, 1); + compare_6d(2000000, 1); +} diff --git a/test/check/speed_vs_root.cpp b/test/check/speed_root.cpp similarity index 100% rename from test/check/speed_vs_root.cpp rename to test/check/speed_root.cpp diff --git a/test/histogram_test.cpp b/test/histogram_test.cpp index 9733529b..061dcf4d 100644 --- a/test/histogram_test.cpp +++ b/test/histogram_test.cpp @@ -4,149 +4,146 @@ // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) -#include #define BOOST_TEST_MODULE histogram_test +#include #include #include -#include -#include -#include #include -using namespace boost::assign; using namespace boost::histogram; BOOST_AUTO_TEST_CASE(init_0) { - histogram(); + auto h = histogram(); + BOOST_CHECK_EQUAL(h.dim(), 0); + BOOST_CHECK_EQUAL(h.size(), 0); } BOOST_AUTO_TEST_CASE(init_1) { - histogram(regular_axis(3, -1, 1)); + auto h = histogram(regular_axis{3, -1, 1}); + BOOST_CHECK_EQUAL(h.dim(), 1); + BOOST_CHECK_EQUAL(h.size(), 5); + BOOST_CHECK_EQUAL(h.shape(0), 5); } BOOST_AUTO_TEST_CASE(init_2) { - histogram(regular_axis(3, -1, 1), - integer_axis(-1, 1)); + auto h = histogram(regular_axis{3, -1, 1}, + integer_axis{-1, 1}); + BOOST_CHECK_EQUAL(h.dim(), 2); + BOOST_CHECK_EQUAL(h.size(), 25); + BOOST_CHECK_EQUAL(h.shape(0), 5); + BOOST_CHECK_EQUAL(h.shape(1), 5); } BOOST_AUTO_TEST_CASE(init_3) { - histogram(regular_axis(3, -1, 1), - integer_axis(-1, 1), - polar_axis(3)); + auto h = histogram(regular_axis{3, -1, 1}, + integer_axis{-1, 1}, + polar_axis{3}); + BOOST_CHECK_EQUAL(h.dim(), 3); + BOOST_CHECK_EQUAL(h.size(), 75); } BOOST_AUTO_TEST_CASE(init_4) { - std::vector x; - x += -1, 0, 1; - histogram(regular_axis(3, -1, 1), - integer_axis(-1, 1), - polar_axis(3), - variable_axis(x)); + auto h = histogram(regular_axis{3, -1, 1}, + integer_axis{-1, 1}, + polar_axis{3}, + variable_axis{-1, 0, 1}); + BOOST_CHECK_EQUAL(h.dim(), 4); + BOOST_CHECK_EQUAL(h.size(), 300); } BOOST_AUTO_TEST_CASE(init_5) { - std::vector x; - x += -1, 0, 1; - histogram(regular_axis(3, -1, 1), - integer_axis(-1, 1), - polar_axis(3), - variable_axis(x), - category_axis("A;B;C")); + auto h = histogram(regular_axis{3, -1, 1}, + integer_axis{-1, 1}, + polar_axis{3}, + variable_axis{-1, 0, 1}, + category_axis{"A", "B", "C"}); + BOOST_CHECK_EQUAL(h.dim(), 5); + BOOST_CHECK_EQUAL(h.size(), 900); } -BOOST_AUTO_TEST_CASE(init_max) -{ - #define ARG(z, n, data) regular_axis(1, -1, 1) - histogram( BOOST_PP_ENUM( BOOST_HISTOGRAM_AXIS_LIMIT, ARG, nil ) ); - - histogram( - histogram::axes_type( BOOST_HISTOGRAM_AXIS_LIMIT, - regular_axis(1, -1, 1) ) - ); -} - -BOOST_AUTO_TEST_CASE(too_many_axes) -{ - BOOST_CHECK_THROW( - histogram( - histogram::axes_type( BOOST_PP_INC(BOOST_HISTOGRAM_AXIS_LIMIT), - regular_axis(1, -1, 1) ) - ), - std::logic_error - ); -} - -// BOOST_AUTO_TEST_CASE(bad_alloc) -// { -// BOOST_CHECK_THROW( -// histogram( -// histogram::axes_type( BOOST_HISTOGRAM_AXIS_LIMIT, -// regular_axis(std::numeric_limits::max(), 0, 1)) -// ), -// std::bad_alloc -// ); -// } - BOOST_AUTO_TEST_CASE(copy_ctor) { - histogram h(regular_axis(1, -1, 1), - regular_axis(2, -2, 2)); + auto h = histogram(regular_axis(1, -1, 1), + regular_axis(2, -2, 2)); h.fill(0.0, 0.0); - histogram h2(h); - BOOST_CHECK(h == h2); + auto h2 = histogram_t<2>(h); + BOOST_CHECK(h2 == h); + // auto h3 = histogram_t(h); + // BOOST_CHECK(h3 == h); } BOOST_AUTO_TEST_CASE(copy_assign) { - histogram h(regular_axis(1, -1, 1), - regular_axis(2, -2, 2)); + auto h = histogram(regular_axis(1, -1, 1), + regular_axis(2, -2, 2)); h.fill(0.0, 0.0); - histogram h2; + auto h2 = histogram_t<2>(); BOOST_CHECK(!(h == h2)); h2 = h; BOOST_CHECK(h == h2); // test self-assign h2 = h2; BOOST_CHECK(h == h2); + // auto h3 = histogram_t(); + // h3 = h; + // BOOST_CHECK(h == h3); } BOOST_AUTO_TEST_CASE(move_ctor) { - histogram h(regular_axis(1, -1, 1), - regular_axis(2, -2, 2)); + auto h = histogram(regular_axis(1, -1, 1), + regular_axis(2, -2, 2)); h.fill(0.0, 0.0); - histogram h2(::boost::move(h)); + auto h2 = histogram_t<2>(std::move(h)); BOOST_CHECK_EQUAL(h2.sum(), 1); BOOST_CHECK_EQUAL(h2.dim(), 2); BOOST_CHECK_EQUAL(h.sum(), 0); - BOOST_CHECK_EQUAL(h.dim(), 0); + BOOST_CHECK_EQUAL(h.dim(), 2); + // auto h3 = histogram_t(std::move(h2)); + // BOOST_CHECK_EQUAL(h3.sum(), 1); + // BOOST_CHECK_EQUAL(h3.dim(), 2); + // BOOST_CHECK_EQUAL(h2.sum(), 0); + // BOOST_CHECK_EQUAL(h2.dim(), 0); +} + +BOOST_AUTO_TEST_CASE(self_move_assign) +{ + auto h = histogram(regular_axis(1, -1, 1), + regular_axis(2, -2, 2)); + h = std::move(h); } BOOST_AUTO_TEST_CASE(move_assign) { - histogram h(regular_axis(1, -1, 1), - regular_axis(2, -2, 2)); + auto h = histogram(regular_axis(1, -1, 1), + regular_axis(2, -2, 2)); h.fill(0.0, 0.0); - histogram h2; - h2 = ::boost::move(h); + auto h2 = histogram_t<2>(); + h2 = std::move(h); BOOST_CHECK_EQUAL(h2.sum(), 1); BOOST_CHECK_EQUAL(h2.dim(), 2); BOOST_CHECK_EQUAL(h.sum(), 0); - BOOST_CHECK_EQUAL(h.dim(), 0); + BOOST_CHECK_EQUAL(h.dim(), 2); // test self-move - h2 = ::boost::move(h2); + h2 = std::move(h2); BOOST_CHECK_EQUAL(h2.sum(), 1); BOOST_CHECK_EQUAL(h2.dim(), 2); + // auto h3 = histogram_t(); + // h3 = std::move(h2); + // BOOST_CHECK_EQUAL(h3.sum(), 1); + // BOOST_CHECK_EQUAL(h3.dim(), 2); + // BOOST_CHECK_EQUAL(h2.sum(), 0); + // BOOST_CHECK_EQUAL(h2.dim(), 0); } BOOST_AUTO_TEST_CASE(d1) { - histogram h(regular_axis(2, -1, 1)); + auto h = histogram(regular_axis(2, -1, 1)); h.fill(-1); h.fill(-1.0); h.fill(-2.0); @@ -168,153 +165,153 @@ BOOST_AUTO_TEST_CASE(d1) BOOST_CHECK_EQUAL(h.variance(2), 1.0); } -BOOST_AUTO_TEST_CASE(d1w) -{ - histogram h(regular_axis(2, -1, 1)); - h.fill(0); - h.wfill(-1.0, 2.0); - h.fill(-1.0); - h.fill(-2.0); - h.wfill(10.0, 5.0); +// BOOST_AUTO_TEST_CASE(d1w) +// { +// histogram h(regular_axis(2, -1, 1)); +// h.fill(0); +// h.wfill(-1.0, 2.0); +// h.fill(-1.0); +// h.fill(-2.0); +// h.wfill(10.0, 5.0); - BOOST_CHECK_EQUAL(h.sum(), 10); +// BOOST_CHECK_EQUAL(h.sum(), 10); - BOOST_CHECK_EQUAL(h.value(-1), 1.0); - BOOST_CHECK_EQUAL(h.value(0), 3.0); - BOOST_CHECK_EQUAL(h.value(1), 1.0); - BOOST_CHECK_EQUAL(h.value(2), 5.0); +// BOOST_CHECK_EQUAL(h.value(-1), 1.0); +// BOOST_CHECK_EQUAL(h.value(0), 3.0); +// BOOST_CHECK_EQUAL(h.value(1), 1.0); +// BOOST_CHECK_EQUAL(h.value(2), 5.0); - BOOST_CHECK_EQUAL(h.variance(-1), 1.0); - BOOST_CHECK_EQUAL(h.variance(0), 5.0); - BOOST_CHECK_EQUAL(h.variance(1), 1.0); - BOOST_CHECK_EQUAL(h.variance(2), 25.0); -} +// BOOST_CHECK_EQUAL(h.variance(-1), 1.0); +// BOOST_CHECK_EQUAL(h.variance(0), 5.0); +// BOOST_CHECK_EQUAL(h.variance(1), 1.0); +// BOOST_CHECK_EQUAL(h.variance(2), 25.0); +// } BOOST_AUTO_TEST_CASE(d2) { - histogram h(regular_axis(2, -1, 1), - integer_axis(-1, 1, std::string(), false)); + auto h = histogram(regular_axis(2, -1, 1), + integer_axis(-1, 1, std::string(), false)); h.fill(-1, -1); h.fill(-1, 0); h.fill(-1, -10); h.fill(-10, 0); - BOOST_CHECK_EQUAL(h.dim(), 2); - BOOST_CHECK_EQUAL(h.bins(0), 2); - BOOST_CHECK_EQUAL(h.shape(0), 4); - BOOST_CHECK_EQUAL(h.bins(1), 3); - BOOST_CHECK_EQUAL(h.shape(1), 3); - BOOST_CHECK_EQUAL(h.sum(), 3); + // BOOST_CHECK_EQUAL(h.dim(), 2); + // BOOST_CHECK_EQUAL(h.bins(0), 2); + // BOOST_CHECK_EQUAL(h.shape(0), 4); + // BOOST_CHECK_EQUAL(h.bins(1), 3); + // BOOST_CHECK_EQUAL(h.shape(1), 3); + // BOOST_CHECK_EQUAL(h.sum(), 3); - BOOST_CHECK_EQUAL(h.value(-1, 0), 0.0); - BOOST_CHECK_EQUAL(h.value(-1, 1), 1.0); - BOOST_CHECK_EQUAL(h.value(-1, 2), 0.0); + // BOOST_CHECK_EQUAL(h.value(-1, 0), 0.0); + // BOOST_CHECK_EQUAL(h.value(-1, 1), 1.0); + // BOOST_CHECK_EQUAL(h.value(-1, 2), 0.0); - BOOST_CHECK_EQUAL(h.value(0, 0), 1.0); - BOOST_CHECK_EQUAL(h.value(0, 1), 1.0); - BOOST_CHECK_EQUAL(h.value(0, 2), 0.0); + // BOOST_CHECK_EQUAL(h.value(0, 0), 1.0); + // BOOST_CHECK_EQUAL(h.value(0, 1), 1.0); + // BOOST_CHECK_EQUAL(h.value(0, 2), 0.0); - BOOST_CHECK_EQUAL(h.value(1, 0), 0.0); - BOOST_CHECK_EQUAL(h.value(1, 1), 0.0); - BOOST_CHECK_EQUAL(h.value(1, 2), 0.0); + // BOOST_CHECK_EQUAL(h.value(1, 0), 0.0); + // BOOST_CHECK_EQUAL(h.value(1, 1), 0.0); + // BOOST_CHECK_EQUAL(h.value(1, 2), 0.0); - BOOST_CHECK_EQUAL(h.value(2, 0), 0.0); - BOOST_CHECK_EQUAL(h.value(2, 1), 0.0); - BOOST_CHECK_EQUAL(h.value(2, 2), 0.0); + // BOOST_CHECK_EQUAL(h.value(2, 0), 0.0); + // BOOST_CHECK_EQUAL(h.value(2, 1), 0.0); + // BOOST_CHECK_EQUAL(h.value(2, 2), 0.0); - BOOST_CHECK_EQUAL(h.variance(-1, 0), 0.0); - BOOST_CHECK_EQUAL(h.variance(-1, 1), 1.0); - BOOST_CHECK_EQUAL(h.variance(-1, 2), 0.0); + // BOOST_CHECK_EQUAL(h.variance(-1, 0), 0.0); + // BOOST_CHECK_EQUAL(h.variance(-1, 1), 1.0); + // BOOST_CHECK_EQUAL(h.variance(-1, 2), 0.0); - BOOST_CHECK_EQUAL(h.variance(0, 0), 1.0); - BOOST_CHECK_EQUAL(h.variance(0, 1), 1.0); - BOOST_CHECK_EQUAL(h.variance(0, 2), 0.0); + // BOOST_CHECK_EQUAL(h.variance(0, 0), 1.0); + // BOOST_CHECK_EQUAL(h.variance(0, 1), 1.0); + // BOOST_CHECK_EQUAL(h.variance(0, 2), 0.0); - BOOST_CHECK_EQUAL(h.variance(1, 0), 0.0); - BOOST_CHECK_EQUAL(h.variance(1, 1), 0.0); - BOOST_CHECK_EQUAL(h.variance(1, 2), 0.0); + // BOOST_CHECK_EQUAL(h.variance(1, 0), 0.0); + // BOOST_CHECK_EQUAL(h.variance(1, 1), 0.0); + // BOOST_CHECK_EQUAL(h.variance(1, 2), 0.0); - BOOST_CHECK_EQUAL(h.variance(2, 0), 0.0); - BOOST_CHECK_EQUAL(h.variance(2, 1), 0.0); - BOOST_CHECK_EQUAL(h.variance(2, 2), 0.0); + // BOOST_CHECK_EQUAL(h.variance(2, 0), 0.0); + // BOOST_CHECK_EQUAL(h.variance(2, 1), 0.0); + // BOOST_CHECK_EQUAL(h.variance(2, 2), 0.0); } -BOOST_AUTO_TEST_CASE(d2w) -{ - histogram h(regular_axis(2, -1, 1), - integer_axis(-1, 1, std::string(), false)); - h.fill(-1, 0); // -> 0, 1 - h.wfill(-1, -1, 10); // -> 0, 0 - h.wfill(-1, -10, 5); // is ignored - h.wfill(-10, 0, 7); // -> -1, 1 +// BOOST_AUTO_TEST_CASE(d2w) +// { +// histogram h(regular_axis(2, -1, 1), +// integer_axis(-1, 1, std::string(), false)); +// h.fill(-1, 0); // -> 0, 1 +// h.wfill(-1, -1, 10); // -> 0, 0 +// h.wfill(-1, -10, 5); // is ignored +// h.wfill(-10, 0, 7); // -> -1, 1 - BOOST_CHECK_EQUAL(h.sum(), 18); +// BOOST_CHECK_EQUAL(h.sum(), 18); - BOOST_CHECK_EQUAL(h.value(-1, 0), 0.0); - BOOST_CHECK_EQUAL(h.value(-1, 1), 7.0); - BOOST_CHECK_EQUAL(h.value(-1, 2), 0.0); +// BOOST_CHECK_EQUAL(h.value(-1, 0), 0.0); +// BOOST_CHECK_EQUAL(h.value(-1, 1), 7.0); +// BOOST_CHECK_EQUAL(h.value(-1, 2), 0.0); - BOOST_CHECK_EQUAL(h.value(0, 0), 10.0); - BOOST_CHECK_EQUAL(h.value(0, 1), 1.0); - BOOST_CHECK_EQUAL(h.value(0, 2), 0.0); +// BOOST_CHECK_EQUAL(h.value(0, 0), 10.0); +// BOOST_CHECK_EQUAL(h.value(0, 1), 1.0); +// BOOST_CHECK_EQUAL(h.value(0, 2), 0.0); - BOOST_CHECK_EQUAL(h.value(1, 0), 0.0); - BOOST_CHECK_EQUAL(h.value(1, 1), 0.0); - BOOST_CHECK_EQUAL(h.value(1, 2), 0.0); +// BOOST_CHECK_EQUAL(h.value(1, 0), 0.0); +// BOOST_CHECK_EQUAL(h.value(1, 1), 0.0); +// BOOST_CHECK_EQUAL(h.value(1, 2), 0.0); - BOOST_CHECK_EQUAL(h.value(2, 0), 0.0); - BOOST_CHECK_EQUAL(h.value(2, 1), 0.0); - BOOST_CHECK_EQUAL(h.value(2, 2), 0.0); +// BOOST_CHECK_EQUAL(h.value(2, 0), 0.0); +// BOOST_CHECK_EQUAL(h.value(2, 1), 0.0); +// BOOST_CHECK_EQUAL(h.value(2, 2), 0.0); - BOOST_CHECK_EQUAL(h.variance(-1, 0), 0.0); - BOOST_CHECK_EQUAL(h.variance(-1, 1), 49.0); - BOOST_CHECK_EQUAL(h.variance(-1, 2), 0.0); +// BOOST_CHECK_EQUAL(h.variance(-1, 0), 0.0); +// BOOST_CHECK_EQUAL(h.variance(-1, 1), 49.0); +// BOOST_CHECK_EQUAL(h.variance(-1, 2), 0.0); - BOOST_CHECK_EQUAL(h.variance(0, 0), 100.0); - BOOST_CHECK_EQUAL(h.variance(0, 1), 1.0); - BOOST_CHECK_EQUAL(h.variance(0, 2), 0.0); +// BOOST_CHECK_EQUAL(h.variance(0, 0), 100.0); +// BOOST_CHECK_EQUAL(h.variance(0, 1), 1.0); +// BOOST_CHECK_EQUAL(h.variance(0, 2), 0.0); - BOOST_CHECK_EQUAL(h.variance(1, 0), 0.0); - BOOST_CHECK_EQUAL(h.variance(1, 1), 0.0); - BOOST_CHECK_EQUAL(h.variance(1, 2), 0.0); +// BOOST_CHECK_EQUAL(h.variance(1, 0), 0.0); +// BOOST_CHECK_EQUAL(h.variance(1, 1), 0.0); +// BOOST_CHECK_EQUAL(h.variance(1, 2), 0.0); - BOOST_CHECK_EQUAL(h.variance(2, 0), 0.0); - BOOST_CHECK_EQUAL(h.variance(2, 1), 0.0); - BOOST_CHECK_EQUAL(h.variance(2, 2), 0.0); -} +// BOOST_CHECK_EQUAL(h.variance(2, 0), 0.0); +// BOOST_CHECK_EQUAL(h.variance(2, 1), 0.0); +// BOOST_CHECK_EQUAL(h.variance(2, 2), 0.0); +// } -BOOST_AUTO_TEST_CASE(add_0) -{ - histogram a(integer_axis(-1, 1)); - histogram b(regular_axis(3, -1, 1)); - BOOST_CHECK_THROW(a + b, std::logic_error); -} +// BOOST_AUTO_TEST_CASE(add_0) +// { +// histogram a(integer_axis(-1, 1)); +// histogram b(regular_axis(3, -1, 1)); +// BOOST_CHECK_THROW(a + b, std::logic_error); +// } -BOOST_AUTO_TEST_CASE(add_1) -{ - histogram a(integer_axis(-1, 1)); - histogram b(integer_axis(-1, 1)); - a.fill(0); - b.fill(-1); - histogram c = a + b; - BOOST_CHECK_EQUAL(c.value(-1), 0); - BOOST_CHECK_EQUAL(c.value(0), 1); - BOOST_CHECK_EQUAL(c.value(1), 1); - BOOST_CHECK_EQUAL(c.value(2), 0); - BOOST_CHECK_EQUAL(c.value(3), 0); -} +// BOOST_AUTO_TEST_CASE(add_1) +// { +// histogram a(integer_axis(-1, 1)); +// histogram b(integer_axis(-1, 1)); +// a.fill(0); +// b.fill(-1); +// histogram c = a + b; +// BOOST_CHECK_EQUAL(c.value(-1), 0); +// BOOST_CHECK_EQUAL(c.value(0), 1); +// BOOST_CHECK_EQUAL(c.value(1), 1); +// BOOST_CHECK_EQUAL(c.value(2), 0); +// BOOST_CHECK_EQUAL(c.value(3), 0); +// } -BOOST_AUTO_TEST_CASE(add_2) -{ - histogram a(integer_axis(-1, 1)); - histogram b(integer_axis(-1, 1)); +// BOOST_AUTO_TEST_CASE(add_2) +// { +// histogram a(integer_axis(-1, 1)); +// histogram b(integer_axis(-1, 1)); - a.fill(0); - b.wfill(-1, 3); - histogram c = a + b; - BOOST_CHECK_EQUAL(c.value(-1), 0); - BOOST_CHECK_EQUAL(c.value(0), 3); - BOOST_CHECK_EQUAL(c.value(1), 1); - BOOST_CHECK_EQUAL(c.value(2), 0); - BOOST_CHECK_EQUAL(c.value(3), 0); -} +// a.fill(0); +// b.wfill(-1, 3); +// histogram c = a + b; +// BOOST_CHECK_EQUAL(c.value(-1), 0); +// BOOST_CHECK_EQUAL(c.value(0), 3); +// BOOST_CHECK_EQUAL(c.value(1), 1); +// BOOST_CHECK_EQUAL(c.value(2), 0); +// BOOST_CHECK_EQUAL(c.value(3), 0); +// } diff --git a/test/python_suite_test.py.in b/test/python_suite_test.py.in deleted file mode 100755 index 93d8f5c9..00000000 --- a/test/python_suite_test.py.in +++ /dev/null @@ -1,657 +0,0 @@ -#!@PYTHON_EXECUTABLE@ -import unittest -from math import pi -from histogram import histogram, regular_axis, polar_axis, \ - variable_axis, category_axis, integer_axis -import pickle -import os -if @PYTHON_VERSION_MAJOR@ == 3: - from io import BytesIO -else: - from StringIO import StringIO as BytesIO - -have_numpy = "@HAVE_NUMPY@" -if have_numpy: - import numpy - -class test_regular_axis(unittest.TestCase): - - def test_init(self): - regular_axis(1, 1.0, 2.0) - regular_axis(1, 1.0, 2.0, label="ra") - regular_axis(1, 1.0, 2.0, uoflow=False) - regular_axis(1, 1.0, 2.0, label="ra", uoflow=False) - with self.assertRaises(TypeError): - regular_axis() - with self.assertRaises(TypeError): - regular_axis(1) - with self.assertRaises(TypeError): - regular_axis(1, 1.0) - with self.assertRaises(RuntimeError): - regular_axis(0, 1.0, 2.0) - with self.assertRaises(TypeError): - regular_axis("1", 1.0, 2.0) - with self.assertRaises(Exception): - regular_axis(-1, 1.0, 2.0) - with self.assertRaises(RuntimeError): - regular_axis(1, 2.0, 1.0) - with self.assertRaises(TypeError): - regular_axis(1, 1.0, 2.0, label=0) - with self.assertRaises(TypeError): - regular_axis(1, 1.0, 2.0, label="ra", uoflow="True") - with self.assertRaises(TypeError): - regular_axis(1, 1.0, 2.0, bad_keyword="ra") - a = regular_axis(4, 1.0, 2.0) - self.assertEqual(a, regular_axis(4, 1.0, 2.0)) - self.assertNotEqual(a, regular_axis(3, 1.0, 2.0)) - self.assertNotEqual(a, regular_axis(4, 1.1, 2.0)) - self.assertNotEqual(a, regular_axis(4, 1.0, 2.1)) - - def test_len(self): - a = regular_axis(4, 1.0, 2.0) - self.assertEqual(len(a), 5) - - def test_repr(self): - for s in ("regular_axis(4, 1.1, 2.2)", - "regular_axis(4, 1.1, 2.2, label='ra')", - "regular_axis(4, 1.1, 2.2, uoflow=False)", - "regular_axis(4, 1.1, 2.2, label='ra', uoflow=False)"): - self.assertEqual(str(eval(s)), s) - - def test_getitem(self): - v = [1.0, 1.25, 1.5, 1.75, 2.0] - a = regular_axis(4, 1.0, 2.0) - for i in range(5): - self.assertEqual(a[i], v[i]) - - def test_iter(self): - v = [1.0, 1.25, 1.5, 1.75, 2.0] - a = regular_axis(4, 1.0, 2.0) - self.assertEqual([x for x in a], v) - - def test_index(self): - a = regular_axis(4, 1.0, 2.0) - self.assertEqual(a.index(-1), -1) - self.assertEqual(a.index(0.99), -1) - self.assertEqual(a.index(1.0), 0) - self.assertEqual(a.index(1.1), 0) - self.assertEqual(a.index(1.249), 0) - self.assertEqual(a.index(1.250), 1) - self.assertEqual(a.index(1.499), 1) - self.assertEqual(a.index(1.500), 2) - self.assertEqual(a.index(1.749), 2) - self.assertEqual(a.index(1.750), 3) - self.assertEqual(a.index(1.999), 3) - self.assertEqual(a.index(2.000), 4) - self.assertEqual(a.index(2.1), 4) - self.assertEqual(a.index(20), 4) - -class test_polar_axis(unittest.TestCase): - - def test_init(self): - polar_axis(1) - polar_axis(4, 1.0) - polar_axis(4, 1.0, label="pa") - with self.assertRaises(TypeError): - polar_axis() - with self.assertRaises(Exception): - polar_axis(-1) - with self.assertRaises(TypeError): - polar_axis(4, 1.0, uoflow=True) - with self.assertRaises(TypeError): - polar_axis(1, 1.0, 2.0) - with self.assertRaises(TypeError): - polar_axis(1, 1.0, label=1) - with self.assertRaises(TypeError): - polar_axis("1") - a = polar_axis(4, 1.0) - self.assertEqual(a, polar_axis(4, 1.0)) - self.assertNotEqual(a, polar_axis(2, 1.0)) - self.assertNotEqual(a, polar_axis(4, 0.0)) - - def test_len(self): - self.assertEqual(len(polar_axis(4)), 5) - self.assertEqual(len(polar_axis(4, 1.0)), 5) - - def test_repr(self): - for s in ("polar_axis(4)", - "polar_axis(4, 1)", - "polar_axis(4, 1, label='x')", - "polar_axis(4, label='x')"): - self.assertEqual(str(eval(s)), s) - - def test_getitem(self): - v = [1.0, 1.0 + 0.5 * pi, 1.0 + pi, 1.0 + 1.5 *pi, 1.0 + 2.0 * pi] - a = polar_axis(4, 1.0) - for i in range(5): - self.assertEqual(a[i], v[i]) - - def test_iter(self): - a = polar_axis(4, 1.0) - v = [1.0, 1.0 + 0.5 * pi, 1.0 + pi, 1.0 + 1.5 *pi, 1.0 + 2.0 * pi] - self.assertEqual([x for x in a], v) - - def test_index(self): - a = polar_axis(4, 1.0) - d = 0.5 * pi - self.assertEqual(a.index(0.99 - 4*d), 3) - self.assertEqual(a.index(0.99 - 3*d), 0) - self.assertEqual(a.index(0.99 - 2*d), 1) - self.assertEqual(a.index(0.99 - d), 2) - self.assertEqual(a.index(0.99), 3) - self.assertEqual(a.index(1.0), 0) - self.assertEqual(a.index(1.01), 0) - self.assertEqual(a.index(0.99 + d), 0) - self.assertEqual(a.index(1.0 + d), 1) - self.assertEqual(a.index(1.0 + 2*d), 2) - self.assertEqual(a.index(1.0 + 3*d), 3) - self.assertEqual(a.index(1.0 + 4*d), 0) - self.assertEqual(a.index(1.0 + 5*d), 1) - -class test_variable_axis(unittest.TestCase): - - def test_init(self): - variable_axis(0, 1) - variable_axis(1, -1) - variable_axis(0, 1, 2, 3, 4) - variable_axis(0, 1, label="va") - variable_axis(0, 1, uoflow=True) - variable_axis(0, 1, label="va", uoflow=True) - with self.assertRaises(TypeError): - variable_axis() - with self.assertRaises(RuntimeError): - variable_axis(1.0) - with self.assertRaises(TypeError): - variable_axis("1", 2) - with self.assertRaises(TypeError): - regular_axis(1, 1.0, 2.0, bad_keyword="ra") - a = variable_axis(-0.1, 0.2, 0.3) - self.assertEqual(a, variable_axis(-0.1, 0.2, 0.3)) - self.assertNotEqual(a, variable_axis(0, 0.2, 0.3)) - self.assertNotEqual(a, variable_axis(-0.1, 0.1, 0.3)) - self.assertNotEqual(a, variable_axis(-0.1, 0.1)) - - def test_len(self): - self.assertEqual(len(variable_axis(-0.1, 0.2, 0.3)), 3) - - def test_repr(self): - for s in ("variable_axis(-0.1, 0.2)", - "variable_axis(-0.1, 0.2, 0.3)", - "variable_axis(-0.1, 0.2, 0.3, label='va')", - "variable_axis(-0.1, 0.2, 0.3, uoflow=False)", - "variable_axis(-0.1, 0.2, 0.3, label='va', uoflow=False)"): - self.assertEqual(str(eval(s)), s) - - def test_getitem(self): - v = [-0.1, 0.2, 0.3] - a = variable_axis(*v) - for i in range(3): - self.assertEqual(a[i], v[i]) - - def test_iter(self): - v = [-0.1, 0.2, 0.3] - a = variable_axis(*v) - self.assertEqual([x for x in a], v) - - def test_index(self): - a = variable_axis(-0.1, 0.2, 0.3) - self.assertEqual(a.index(-10.0), -1) - self.assertEqual(a.index(-0.11), -1) - self.assertEqual(a.index(-0.1), 0) - self.assertEqual(a.index(0.0), 0) - self.assertEqual(a.index(0.19), 0) - self.assertEqual(a.index(0.2), 1) - self.assertEqual(a.index(0.21), 1) - self.assertEqual(a.index(0.29), 1) - self.assertEqual(a.index(0.3), 2) - self.assertEqual(a.index(0.31), 2) - self.assertEqual(a.index(10), 2) - -class test_category_axis(unittest.TestCase): - - def test_init(self): - category_axis("A", "B", "C") - category_axis("A;B;C") - with self.assertRaises(TypeError): - category_axis() - with self.assertRaises(TypeError): - category_axis(1) - with self.assertRaises(TypeError): - category_axis("1", 2) - with self.assertRaises(TypeError): - category_axis("A", "B", "C", label="ca") - with self.assertRaises(TypeError): - category_axis("A", "B", "C", uoflow=True) - self.assertEqual(category_axis("A", "B", "C"), - category_axis("A", "B", "C")) - self.assertEqual(category_axis("A", "B", "C"), - category_axis("A;B;C")) - self.assertEqual(category_axis(";"), category_axis("", "")) - self.assertEqual(category_axis("abc;d"), category_axis("abc", "d")) - self.assertEqual(category_axis("a;bcd"), category_axis("a", "bcd")) - self.assertNotEqual(category_axis("A;B"), category_axis("A;C")) - - def test_len(self): - a = category_axis("A", "B", "C") - self.assertEqual(len(a), 3) - a = category_axis("A;B;C") - self.assertEqual(len(a), 3) - - def test_repr(self): - for s in ("category_axis('A')", - "category_axis('A', 'B')", - "category_axis('A', 'B', 'C')"): - self.assertEqual(str(eval(s)), s) - - def test_getitem(self): - c = "A", "B", "C" - a = category_axis(*c) - for i in range(3): - self.assertEqual(a[i], c[i]) - - def test_iter(self): - c = ["A", "B", "C"] - self.assertEqual([x for x in category_axis(*c)], c) - -class test_integer_axis(unittest.TestCase): - - def test_init(self): - integer_axis(-1, 2) - with self.assertRaises(TypeError): - integer_axis() - with self.assertRaises(TypeError): - integer_axis(1) - with self.assertRaises(TypeError): - integer_axis("1", 2) - with self.assertRaises(RuntimeError): - integer_axis(2, -1) - with self.assertRaises(TypeError): - integer_axis(1, 2, 3) - self.assertEqual(integer_axis(-1, 2), integer_axis(-1, 2)) - self.assertNotEqual(integer_axis(-1, 2), integer_axis(-1, 2, label="ia")) - self.assertNotEqual(integer_axis(-1, 2, uoflow=False), - integer_axis(-1, 2, uoflow=True)) - - def test_len(self): - self.assertEqual(len(integer_axis(-1, 2)), 4) - - def test_repr(self): - for s in ("integer_axis(-1, 1)", - "integer_axis(-1, 1, label='ia')", - "integer_axis(-1, 1, uoflow=False)", - "integer_axis(-1, 1, label='ia', uoflow=False)"): - self.assertEqual(str(eval(s)), s) - - def test_label(self): - self.assertEqual(integer_axis(-1, 2, label="ia").label, "ia") - - def test_getitem(self): - v = [-1, 0, 1, 2] - a = integer_axis(-1, 2) - for i in range(4): - self.assertEqual(a[i], v[i]) - - def test_iter(self): - v = [x for x in integer_axis(-1, 2)] - self.assertEqual(v, [-1, 0, 1, 2]) - - def test_index(self): - a = integer_axis(-1, 2) - self.assertEqual(a.index(-3), -1) - self.assertEqual(a.index(-2), -1) - self.assertEqual(a.index(-1), 0) - self.assertEqual(a.index(0), 1) - self.assertEqual(a.index(1), 2) - self.assertEqual(a.index(2), 3) - self.assertEqual(a.index(3), 4) - self.assertEqual(a.index(4), 4) - -class histogram_test(unittest.TestCase): - - def test_init(self): - histogram() - histogram(integer_axis(-1, 1)) - with self.assertRaises(TypeError): - histogram(1) - with self.assertRaises(TypeError): - histogram("bla") - with self.assertRaises(TypeError): - histogram([]) - with self.assertRaises(TypeError): - histogram(regular_axis) - with self.assertRaises(TypeError): - histogram(regular_axis()) - with self.assertRaises(TypeError): - histogram([integer_axis(-1, 1)]) - with self.assertRaises(RuntimeError): - histogram(integer_axis(-1, 1), unknown_keyword="nh") - - h = histogram(integer_axis(-1, 1)) - self.assertEqual(h.dim, 1) - self.assertEqual(h.axis(0), integer_axis(-1, 1)) - self.assertEqual(h.shape(0), 5) - self.assertEqual(h.depth, 1) - self.assertEqual(histogram(integer_axis(-1, 1, uoflow=False)).shape(0), 3) - self.assertNotEqual(h, histogram(regular_axis(1, -1, 1))) - self.assertNotEqual(h, histogram(integer_axis(-1, 2))) - self.assertNotEqual(h, histogram(integer_axis(-1, 1, label="ia"))) - - def test_copy(self): - a = histogram(integer_axis(-1, 1)) - import copy - b = copy.copy(a) - self.assertEqual(a, b) - self.assertNotEqual(id(a), id(b)) - c = copy.deepcopy(b) - self.assertEqual(b, c) - self.assertNotEqual(id(b), id(c)) - - def test_fill_1d(self): - h0 = histogram(integer_axis(-1, 1, uoflow=False)) - h1 = histogram(integer_axis(-1, 1, uoflow=True)) - for h in (h0, h1): - with self.assertRaises(Exception): - h.fill() - with self.assertRaises(Exception): - h.fill(1, 2) - h.fill(-10) - h.fill(-1) - h.fill(-1) - h.fill(0) - h.fill(1) - h.fill(1) - h.fill(1) - h.fill(10) - self.assertEqual(h0.sum, 6) - self.assertEqual(h0.depth, 1) - self.assertEqual(h0.shape(0), 3) - self.assertEqual(h1.sum, 8) - self.assertEqual(h1.depth, 1) - self.assertEqual(h1.shape(0), 5) - - for h in (h0, h1): - self.assertEqual(h.value(0), 2) - self.assertEqual(h.value(1), 1) - self.assertEqual(h.value(2), 3) - with self.assertRaises(RuntimeError): - h.value(0, 1) - - self.assertEqual(h1.value(-1), 1) - self.assertEqual(h1.value(3), 1) - - def test_growth(self): - h = histogram(integer_axis(-1, 1)) - h.fill(-1) - h.fill(1) - h.fill(1) - for i in range(255): - h.fill(0) - self.assertEqual(h.depth, 1) - h.fill(0) - self.assertEqual(h.depth, 2) - for i in range(1000-256): - h.fill(0) - self.assertEqual(h.value(-1), 0) - self.assertEqual(h.value(0), 1) - self.assertEqual(h.value(1), 1000) - self.assertEqual(h.value(2), 2) - self.assertEqual(h.value(3), 0) - - def test_fill_2d(self): - for uoflow in (False, True): - h = histogram(integer_axis(-1, 1, uoflow=uoflow), - regular_axis(4, -2, 2, uoflow=uoflow)) - h.fill(-1, -2) - h.fill(-1, -1) - h.fill(0, 0) - h.fill(0, 1) - h.fill(1, 0) - h.fill(3, -1) - h.fill(0, -3) - with self.assertRaises(Exception): - h.fill(1) - with self.assertRaises(Exception): - h.fill(1, 2, 3) - - m = [[1, 1, 0, 0, 0, 0], - [0, 0, 1, 1, 0, 1], - [0, 0, 1, 0, 0, 0], - [0, 1, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0]] - for i in range(h.axis(0).bins + 2*uoflow): - for j in range(h.axis(1).bins + 2*uoflow): - self.assertEqual(h.value(i, j), m[i][j]) - - def test_add_2d(self): - for uoflow in (False, True): - h = histogram(integer_axis(-1, 1, uoflow=uoflow), - regular_axis(4, -2, 2, uoflow=uoflow)) - h.fill(-1, -2) - h.fill(-1, -1) - h.fill(0, 0) - h.fill(0, 1) - h.fill(1, 0) - h.fill(3, -1) - h.fill(0, -3) - - m = [[1, 1, 0, 0, 0, 0], - [0, 0, 1, 1, 0, 1], - [0, 0, 1, 0, 0, 0], - [0, 1, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0]] - - h2 = h + h - h += h - self.assertEqual(h, h2) - - for i in range(h.axis(0).bins + 2*uoflow): - for j in range(h.axis(1).bins + 2*uoflow): - self.assertEqual(h.value(i, j), 2 * m[i][j]) - self.assertEqual(h.variance(i, j), 2 * m[i][j]) - - def test_add_2d_bad(self): - a = histogram(integer_axis(-1, 1)) - b = histogram(regular_axis(3, -1, 1)) - with self.assertRaises(RuntimeError): - a += b - - def test_add_2d_w(self): - for uoflow in (False, True): - h = histogram(integer_axis(-1, 1, uoflow=uoflow), - regular_axis(4, -2, 2, uoflow=uoflow)) - h.fill(-1, -2) - h.fill(-1, -1) - h.fill(0, 0) - h.fill(0, 1) - h.fill(1, 0) - h.fill(3, -1) - h.fill(0, -3) - - m = [[1, 1, 0, 0, 0, 0], - [0, 0, 1, 1, 0, 1], - [0, 0, 1, 0, 0, 0], - [0, 1, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0]] - - hw = histogram(integer_axis(-1, 1, uoflow=uoflow), - regular_axis(4, -2, 2, uoflow=uoflow)) - hw.fill(0, 0, w=0) - - h2 = h + hw - h += h - self.assertNotEqual(h, h2) - - for i in range(h.axis(0).bins + 2*uoflow): - for j in range(h.axis(1).bins + 2*uoflow): - self.assertEqual(h.value(i, j), 2 * m[i][j]) - self.assertEqual(h.variance(i, j), 2 * m[i][j]) - - def test_pickle_0(self): - a = histogram(category_axis('A', 'B', 'C'), - integer_axis(0, 20, label='ia'), - regular_axis(20, 0.0, 20.0, uoflow=False), - variable_axis(0.0, 1.0, 2.0), - polar_axis(4, label='pa')) - for i in range(a.axis(0).bins): - a.fill(i, 0, 0, 0, 0) - for j in range(a.axis(1).bins): - a.fill(i, j, 0, 0, 0) - for k in range(a.axis(2).bins): - a.fill(i, j, k, 0, 0) - for l in range(a.axis(3).bins): - a.fill(i, j, k, l, 0) - for m in range(a.axis(4).bins): - a.fill(i, j, k, l, m * 0.5 * pi) - - io = BytesIO() - pickle.dump(a, io) - io.seek(0) - b = pickle.load(io) - self.assertNotEqual(id(a), id(b)) - self.assertEqual(a.dim, b.dim) - self.assertEqual(a.axis(0), b.axis(0)) - self.assertEqual(a.axis(1), b.axis(1)) - self.assertEqual(a.axis(2), b.axis(2)) - self.assertEqual(a.axis(3), b.axis(3)) - self.assertEqual(a.axis(4), b.axis(4)) - self.assertEqual(a.sum, b.sum) - self.assertEqual(a, b) - - def test_pickle_1(self): - a = histogram(category_axis('A', 'B', 'C'), - integer_axis(0, 3, label='ia'), - regular_axis(4, 0.0, 4.0, uoflow=False), - variable_axis(0.0, 1.0, 2.0)) - for i in range(a.axis(0).bins): - a.fill(i, 0, 0, 0, w=3) - for j in range(a.axis(1).bins): - a.fill(i, j, 0, 0, w=10) - for k in range(a.axis(2).bins): - a.fill(i, j, k, 0, w=2) - for l in range(a.axis(3).bins): - a.fill(i, j, k, l, w=5) - - io = BytesIO() - pickle.dump(a, io) - io.seek(0) - b = pickle.load(io) - self.assertNotEqual(id(a), id(b)) - self.assertEqual(a.dim, b.dim) - self.assertEqual(a.axis(0), b.axis(0)) - self.assertEqual(a.axis(1), b.axis(1)) - self.assertEqual(a.axis(2), b.axis(2)) - self.assertEqual(a.axis(3), b.axis(3)) - self.assertEqual(a.sum, b.sum) - self.assertEqual(a, b) - - @unittest.skipUnless(have_numpy, "requires build with numpy-support") - def test_numpy_conversion_0(self): - a = histogram(integer_axis(0, 2, uoflow=False)) - for i in range(100): - a.fill(1) - b = numpy.array(a) # a copy - v = numpy.asarray(a) # a view - self.assertEqual(b.dtype, numpy.uint8) - self.assertTrue(numpy.all(b == numpy.array((0, 100, 0)))) - for i in range(100): - a.fill(1) - self.assertTrue(numpy.all(b == numpy.array((0, 100, 0)))) - self.assertTrue(numpy.all(v == numpy.array((0, 200, 0)))) - for i in range(100): - a.fill(1) - b = numpy.array(a) - self.assertEqual(b.dtype, numpy.uint16) - self.assertTrue(numpy.all(b == numpy.array((0, 300, 0)))) - # view does not follow underlying switch in word size - self.assertFalse(numpy.all(v == b)) - - @unittest.skipUnless(have_numpy, "requires build with numpy-support") - def test_numpy_conversion_1(self): - a = histogram(integer_axis(0, 2, uoflow=False)) - for i in range(10): - a.fill(1, w=3) - b = numpy.array(a) # a copy - v = numpy.asarray(a) # a view - self.assertEqual(b.dtype, numpy.float64) - self.assertTrue(numpy.all(b == numpy.array(((0, 0), (30, 90), (0, 0))))) - self.assertTrue(numpy.all(v == b)) - - @unittest.skipUnless(have_numpy, "requires build with numpy-support") - def test_fill_with_numpy_array_0(self): - a = histogram(integer_axis(0, 2, uoflow=False)) - a.fill(numpy.array([-1, 0, 1, 2, 1, 4])) - a.fill((-1, 0)) - a.fill([1, 2]) - self.assertEqual(a.value(0), 2) - self.assertEqual(a.value(1), 3) - self.assertEqual(a.value(2), 2) - - with self.assertRaises(ValueError): - a.fill(numpy.empty((2, 2))) - with self.assertRaises(ValueError): - a.fill(numpy.empty((1, 2, 2))) - with self.assertRaises(RuntimeError): - a.fill(numpy.empty((2, 1)), 1) - with self.assertRaises(ValueError): - a.fill("abc") - - a = histogram(integer_axis(0, 1, uoflow=False), - regular_axis(2, 0, 2, uoflow=False)) - a.fill(numpy.array([[-1., -1.], [0., 1.], [1., 0.1]])) - self.assertEqual(a.value(0, 0), 0) - self.assertEqual(a.value(0, 1), 1) - self.assertEqual(a.value(1, 0), 1) - self.assertEqual(a.value(1, 1), 0) - - with self.assertRaises(ValueError): - a.fill((1, 2, 3)) - - a = histogram(integer_axis(0, 2, uoflow=False)) - a.fill([0, 0, 1, 2]) - a.fill((1, 0, 2, 2)) - self.assertEqual(a.value(0), 3) - self.assertEqual(a.value(1), 2) - self.assertEqual(a.value(2), 3) - - - @unittest.skipUnless(have_numpy, "requires build with numpy-support") - def test_fill_with_numpy_array_1(self): - a = histogram(integer_axis(0, 2, uoflow=True)) - v = numpy.array([-1, 0, 1, 2, 3, 4]) - w = numpy.array([ 2, 3, 4, 5, 6, 7]) - a.fill(v, w=w) - a.fill([0, 1], w=[2.0, 3.0]) - self.assertEqual(a.value(-1), 2) - self.assertEqual(a.value(0), 5) - self.assertEqual(a.value(1), 7) - self.assertEqual(a.value(2), 5) - self.assertEqual(a.variance(-1), 4) - self.assertEqual(a.variance(0), 13) - self.assertEqual(a.variance(1), 25) - self.assertEqual(a.variance(2), 25) - - with self.assertRaises(RuntimeError): - a.fill([1, 2], foo=1) - with self.assertRaises(RuntimeError): - a.fill([1, 2], w=[1], foo=1) - with self.assertRaises(ValueError): - a.fill([1, 2], w=1) - with self.assertRaises(ValueError): - a.fill([1, 2], w=[[1, 1], [2, 2]]) - - a = histogram(integer_axis(0, 1, uoflow=False), - regular_axis(2, 0, 2, uoflow=False)) - a.fill(numpy.array([[-1., -1.], [0., 1.], [1., 0.1]])) - self.assertEqual(a.value(0, 0), 0) - self.assertEqual(a.value(0, 1), 1) - self.assertEqual(a.value(1, 0), 1) - self.assertEqual(a.value(1, 1), 0) - a = histogram(integer_axis(0, 2, uoflow=False)) - a.fill([0, 0, 1, 2]) - a.fill((1, 0, 2, 2)) - self.assertEqual(a.value(0), 3) - self.assertEqual(a.value(1), 2) - self.assertEqual(a.value(2), 3) - -if __name__ == "__main__": - unittest.main() diff --git a/test/serialization.cpp b/test/serialization.cpp deleted file mode 100644 index f205c21a..00000000 --- a/test/serialization.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015-2016 Hans Dembinski -// -// 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 -#include -#include -#include -#include - -void serialize() -{ - std::fstream fs; - boost::archive::binary_iarchive bi(fs); - boost::archive::binary_oarchive bo(fs); - - boost::histogram::histogram hs; - - bi & hs; - bo & hs; -}