mirror of
https://github.com/boostorg/histogram.git
synced 2025-05-09 23:04:07 +00:00
new feature, filling with weights
This commit is contained in:
parent
14c7a282dc
commit
103fa6cf0a
@ -9,28 +9,30 @@ find_package(Boost 1.55 REQUIRED
|
|||||||
COMPONENTS python iostreams serialization unit_test_framework)
|
COMPONENTS python iostreams serialization unit_test_framework)
|
||||||
find_package(PythonLibs)
|
find_package(PythonLibs)
|
||||||
find_package(Numpy) # optional
|
find_package(Numpy) # optional
|
||||||
find_package(ROOT) # only used in one of the tests
|
|
||||||
|
|
||||||
include_directories(include ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
|
include_directories(include ${Boost_INCLUDE_DIRS})
|
||||||
add_definitions(-DBOOST_TEST_DYN_LINK) # for unit_test_framework
|
add_definitions(-DBOOST_TEST_DYN_LINK) # for unit_test_framework
|
||||||
set(LIBRARIES stdc++ ${Boost_LIBRARIES})
|
set(LIBRARIES stdc++ ${Boost_LIBRARIES})
|
||||||
|
|
||||||
if(Boost_PYTHON_FOUND)
|
if(Boost_PYTHON_FOUND AND PYTHONLIBS_FOUND)
|
||||||
|
set(USE_PYTHON True)
|
||||||
|
include_directories(${PYTHON_INCLUDE_DIRS})
|
||||||
LIST(APPEND LIBRARIES ${PYTHON_LIBRARIES})
|
LIST(APPEND LIBRARIES ${PYTHON_LIBRARIES})
|
||||||
|
add_definitions(-DUSE_PYTHON)
|
||||||
|
|
||||||
|
if(NUMPY_FOUND)
|
||||||
|
include_directories(${NUMPY_INCLUDE_DIR})
|
||||||
|
add_definitions(-DUSE_NUMPY)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NUMPY_FOUND)
|
# core library
|
||||||
include_directories(${NUMPY_INCLUDE_DIR})
|
|
||||||
add_definitions(-DUSE_NUMPY)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(histogram SHARED
|
add_library(histogram SHARED
|
||||||
src/axis.cpp
|
src/axis.cpp
|
||||||
src/histogram_base.cpp
|
src/histogram_base.cpp
|
||||||
src/nhistogram.cpp
|
src/histogram.cpp
|
||||||
src/nstore.cpp
|
src/nstore.cpp
|
||||||
src/zero_suppression.cpp
|
src/zero_suppression.cpp
|
||||||
# src/whistogram.cpp
|
|
||||||
)
|
)
|
||||||
target_link_libraries(histogram ${LIBRARIES})
|
target_link_libraries(histogram ${LIBRARIES})
|
||||||
|
|
||||||
@ -41,21 +43,24 @@ else()
|
|||||||
target_compile_options(histogram PUBLIC "-O3 -fomit-frame-pointer -mtune=generic")
|
target_compile_options(histogram PUBLIC "-O3 -fomit-frame-pointer -mtune=generic")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(Boost_PYTHON_FOUND)
|
# python bindings
|
||||||
|
if(USE_PYTHON)
|
||||||
add_library(pyhistogram MODULE
|
add_library(pyhistogram MODULE
|
||||||
src/python/module.cpp
|
src/python/module.cpp
|
||||||
src/python/histogram_base.cpp
|
src/python/histogram_base.cpp
|
||||||
src/python/nhistogram.cpp
|
src/python/histogram.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(pyhistogram histogram ${LIBRARIES})
|
target_link_libraries(pyhistogram histogram ${LIBRARIES})
|
||||||
set_target_properties(pyhistogram PROPERTIES OUTPUT_NAME "histogram" PREFIX "" SUFFIX ".so")
|
set_target_properties(pyhistogram PROPERTIES OUTPUT_NAME "histogram" PREFIX "" SUFFIX ".so")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# examples
|
||||||
add_executable(sizeof
|
add_executable(sizeof
|
||||||
examples/sizeof.cpp
|
examples/sizeof.cpp
|
||||||
)
|
)
|
||||||
target_link_libraries(sizeof ${LIBRARIES})
|
target_link_libraries(sizeof ${LIBRARIES})
|
||||||
|
|
||||||
|
find_package(ROOT) # only used in speed comparison
|
||||||
if(ROOT_FOUND)
|
if(ROOT_FOUND)
|
||||||
add_executable(nhistogram_speed
|
add_executable(nhistogram_speed
|
||||||
examples/speed_vs_root.cpp)
|
examples/speed_vs_root.cpp)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <boost/histogram/nhistogram.hpp>
|
#include <boost/histogram/histogram.hpp>
|
||||||
#include <boost/histogram/axis.hpp>
|
#include <boost/histogram/axis.hpp>
|
||||||
#include <boost/random.hpp>
|
#include <boost/random.hpp>
|
||||||
#include <boost/array.hpp>
|
#include <boost/array.hpp>
|
||||||
@ -51,7 +51,7 @@ void compare_1d(unsigned n)
|
|||||||
t = clock() - t;
|
t = clock() - t;
|
||||||
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
nhistogram h(regular_axis(100, 0, 1));
|
histogram h(regular_axis(100, 0, 1));
|
||||||
t = clock();
|
t = clock();
|
||||||
for (unsigned i = 0; i < n; ++i)
|
for (unsigned i = 0; i < n; ++i)
|
||||||
h.fill(r[i]);
|
h.fill(r[i]);
|
||||||
@ -80,7 +80,7 @@ void compare_3d(unsigned n)
|
|||||||
t = clock() - t;
|
t = clock() - t;
|
||||||
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
nhistogram h(regular_axis(100, 0, 1),
|
histogram h(regular_axis(100, 0, 1),
|
||||||
regular_axis(100, 0, 1),
|
regular_axis(100, 0, 1),
|
||||||
regular_axis(100, 0, 1));
|
regular_axis(100, 0, 1));
|
||||||
t = clock();
|
t = clock();
|
||||||
@ -118,7 +118,7 @@ void compare_6d(unsigned n)
|
|||||||
t = clock() - t;
|
t = clock() - t;
|
||||||
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
best_root = std::min(best_root, double(t) / CLOCKS_PER_SEC);
|
||||||
|
|
||||||
nhistogram h(regular_axis(10, 0, 1),
|
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),
|
regular_axis(10, 0, 1),
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
#ifndef _BOOST_HISTOGRAM_NSTORE_HPP_
|
#ifndef _BOOST_HISTOGRAM_DETAIL_NSTORE_HPP_
|
||||||
#define _BOOST_HISTOGRAM_NSTORE_HPP_
|
#define _BOOST_HISTOGRAM_DETAIL_NSTORE_HPP_
|
||||||
|
|
||||||
|
#include <boost/histogram/detail/wtype.hpp>
|
||||||
|
#include <boost/histogram/detail/zero_suppression.hpp>
|
||||||
#include <boost/serialization/access.hpp>
|
#include <boost/serialization/access.hpp>
|
||||||
#include <boost/serialization/array.hpp>
|
#include <boost/serialization/array.hpp>
|
||||||
#include <boost/histogram/detail/zero_suppression.hpp>
|
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
#include <boost/assert.hpp>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@ -20,7 +22,6 @@ class nstore {
|
|||||||
public:
|
public:
|
||||||
typedef uintptr_t size_type;
|
typedef uintptr_t size_type;
|
||||||
|
|
||||||
public:
|
|
||||||
nstore();
|
nstore();
|
||||||
nstore(const nstore&);
|
nstore(const nstore&);
|
||||||
nstore(size_type, unsigned d = sizeof(uint8_t));
|
nstore(size_type, unsigned d = sizeof(uint8_t));
|
||||||
@ -30,11 +31,12 @@ public:
|
|||||||
nstore& operator+=(const nstore&);
|
nstore& operator+=(const nstore&);
|
||||||
bool operator==(const nstore&) const;
|
bool operator==(const nstore&) const;
|
||||||
|
|
||||||
uint64_t read(size_type) const;
|
|
||||||
void write(size_type, uint64_t);
|
|
||||||
|
|
||||||
inline void increase(size_type i) {
|
inline void increase(size_type i) {
|
||||||
switch (depth_) {
|
switch (depth_) {
|
||||||
|
case sizeof(wtype): {
|
||||||
|
wtype& b = ((wtype*)buffer_)[i];
|
||||||
|
b += 1.0;
|
||||||
|
}
|
||||||
#define BOOST_HISTOGRAM_NSTORE_INC(T) \
|
#define BOOST_HISTOGRAM_NSTORE_INC(T) \
|
||||||
case sizeof(T): { \
|
case sizeof(T): { \
|
||||||
T& b = ((T*)buffer_)[i]; \
|
T& b = ((T*)buffer_)[i]; \
|
||||||
@ -51,6 +53,14 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void increase(size_type i, double w) {
|
||||||
|
assert(depth_ == sizeof(wtype));
|
||||||
|
((wtype*)buffer_)[i] += w;
|
||||||
|
}
|
||||||
|
|
||||||
|
double value(size_type) const;
|
||||||
|
double variance(size_type) const;
|
||||||
|
|
||||||
const void* buffer() const { return buffer_; }
|
const void* buffer() const { return buffer_; }
|
||||||
unsigned depth() const { return depth_; }
|
unsigned depth() const { return depth_; }
|
||||||
|
|
||||||
@ -62,8 +72,24 @@ private:
|
|||||||
void create();
|
void create();
|
||||||
void destroy();
|
void destroy();
|
||||||
void grow();
|
void grow();
|
||||||
|
void wconvert();
|
||||||
|
|
||||||
uint64_t max_count() const;
|
uint64_t max_count() const
|
||||||
|
{
|
||||||
|
switch (depth_) {
|
||||||
|
#define BOOST_HISTOGRAM_NSTORE_CASE(T) \
|
||||||
|
case sizeof(T): return std::numeric_limits<T>::max()
|
||||||
|
BOOST_HISTOGRAM_NSTORE_CASE(uint8_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_CASE(uint16_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_CASE(uint32_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_CASE(uint64_t);
|
||||||
|
#undef BOOST_HISTOGRAM_NSTORE_CASE
|
||||||
|
default: assert(!"invalid depth");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t ivalue(size_type) const;
|
||||||
|
|
||||||
friend class serialization::access;
|
friend class serialization::access;
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
@ -81,26 +107,50 @@ private:
|
|||||||
throw std::bad_alloc();
|
throw std::bad_alloc();
|
||||||
|
|
||||||
if (Archive::is_saving::value) {
|
if (Archive::is_saving::value) {
|
||||||
std::vector<char> buf;
|
switch (depth_) {
|
||||||
if (zero_suppression_encode(buf, size_ * depth_,
|
#define BOOST_HISTOGRAM_NSTORE_SAVE(T) \
|
||||||
(char*)buffer_, size_ * depth_)) {
|
case sizeof(T): { \
|
||||||
bool is_zero_suppressed = true;
|
std::vector<T> buf; \
|
||||||
ar & is_zero_suppressed;
|
if (zero_suppression_encode<T>(buf, (T*)buffer_, size_)) { \
|
||||||
ar & buf;
|
bool is_zero_suppressed = true; \
|
||||||
} else {
|
ar & is_zero_suppressed; \
|
||||||
bool is_zero_suppressed = false;
|
ar & buf; \
|
||||||
ar & is_zero_suppressed;
|
} else { \
|
||||||
ar & serialization::make_array((char*)buffer_, size_ * depth_);
|
bool is_zero_suppressed = false; \
|
||||||
|
ar & is_zero_suppressed; \
|
||||||
|
ar & serialization::make_array((T*)buffer_, size_); \
|
||||||
|
} \
|
||||||
|
} break
|
||||||
|
BOOST_HISTOGRAM_NSTORE_SAVE(uint8_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_SAVE(uint16_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_SAVE(uint32_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_SAVE(uint64_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_SAVE(wtype);
|
||||||
|
#undef BOOST_HISTOGRAM_NSTORE_SAVE
|
||||||
|
default: assert(!"invalid depth");
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (Archive::is_loading::value) {
|
||||||
bool is_zero_suppressed = false;
|
bool is_zero_suppressed = false;
|
||||||
ar & is_zero_suppressed;
|
ar & is_zero_suppressed;
|
||||||
if (is_zero_suppressed) {
|
switch (depth_) {
|
||||||
std::vector<char> buf;
|
#define BOOST_HISTOGRAM_NSTORE_LOAD(T) \
|
||||||
ar & buf;
|
case sizeof(T): \
|
||||||
zero_suppression_decode((char*)buffer_, size_ * depth_, buf);
|
if (is_zero_suppressed) { \
|
||||||
} else {
|
std::vector<T> buf; \
|
||||||
ar & serialization::make_array((char*)buffer_, size_ * depth_);
|
ar & buf; \
|
||||||
|
zero_suppression_decode<T>((T*)buffer_, size_, buf); \
|
||||||
|
} else { \
|
||||||
|
ar & serialization::make_array((T*)buffer_, size_); \
|
||||||
|
} break
|
||||||
|
BOOST_HISTOGRAM_NSTORE_LOAD(uint8_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_LOAD(uint16_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_LOAD(uint32_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_LOAD(uint64_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_LOAD(wtype);
|
||||||
|
#undef BOOST_HISTOGRAM_NSTORE_LOAD
|
||||||
|
default: assert(!"invalid depth");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
47
include/boost/histogram/detail/wtype.hpp
Normal file
47
include/boost/histogram/detail/wtype.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef _BOOST_HISTOGRAM_DETAIL_WTYPE_HPP_
|
||||||
|
#define _BOOST_HISTOGRAM_DETAIL_WTYPE_HPP_
|
||||||
|
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace histogram {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
struct wtype {
|
||||||
|
double w, w2;
|
||||||
|
wtype() : w(0), w2(0) {}
|
||||||
|
wtype(const wtype& o) : w(o.w), w2(o.w2) {}
|
||||||
|
wtype(uint64_t i) : w(i), w2(i) {}
|
||||||
|
wtype& operator+=(const wtype& o)
|
||||||
|
{ w += o.w; w2 += o.w2; return *this; }
|
||||||
|
wtype& operator+=(double v)
|
||||||
|
{ w += v; w2 += v*v; return *this; }
|
||||||
|
wtype& operator=(uint64_t i)
|
||||||
|
{ w = i; w2 = i; return *this; }
|
||||||
|
bool operator==(uint64_t i) const
|
||||||
|
{ return w == i; }
|
||||||
|
bool operator!=(uint64_t i) const
|
||||||
|
{ return w != i; }
|
||||||
|
bool operator==(const wtype& o) const
|
||||||
|
{ return w == o.w && w2 == o.w2; }
|
||||||
|
bool operator!=(const wtype& o) const
|
||||||
|
{ return w != o.w || w2 != o.w2; }
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, unsigned version)
|
||||||
|
{ ar & w; ar & w2; }
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
std::ostream& operator<<(std::ostream& os, const wtype& w)
|
||||||
|
{
|
||||||
|
os << '(' << w.w << ',' << w.w2 << ')';
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,20 +1,80 @@
|
|||||||
#ifndef _BOOST_HISTOGRAM_DETAIL_ZERO_SUPPRESSION_HPP_
|
#ifndef _BOOST_HISTOGRAM_DETAIL_ZERO_SUPPRESSION_HPP_
|
||||||
#define _BOOST_HISTOGRAM_DETAIL_ZERO_SUPPRESSION_HPP_
|
#define _BOOST_HISTOGRAM_DETAIL_ZERO_SUPPRESSION_HPP_
|
||||||
|
|
||||||
#include <cstddef>
|
#include <boost/cstdint.hpp>
|
||||||
|
#include <boost/histogram/detail/wtype.hpp>
|
||||||
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace histogram {
|
namespace histogram {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
bool
|
bool
|
||||||
zero_suppression_encode(std::vector<char>& output, std::size_t output_max,
|
zero_suppression_encode(std::vector<T>& output, const T* input,
|
||||||
const char* input, std::size_t input_len);
|
uintptr_t size)
|
||||||
|
{
|
||||||
|
#define BOOST_HISTOGRAM_ZERO_SUPPRESSION_FILL { \
|
||||||
|
if ((size - output.size()) < 2) \
|
||||||
|
return false; \
|
||||||
|
output.push_back(0); \
|
||||||
|
output.push_back(nzero); \
|
||||||
|
nzero = 0; \
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* input_end = input + size;
|
||||||
|
T nzero = 0;
|
||||||
|
for (; input != input_end; ++input) {
|
||||||
|
if (*input != 0) {
|
||||||
|
if (nzero)
|
||||||
|
BOOST_HISTOGRAM_ZERO_SUPPRESSION_FILL
|
||||||
|
if (output.size() == size)
|
||||||
|
return false;
|
||||||
|
output.push_back(*input);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
++nzero;
|
||||||
|
if (nzero == 0) // overflowed to zero
|
||||||
|
BOOST_HISTOGRAM_ZERO_SUPPRESSION_FILL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nzero)
|
||||||
|
BOOST_HISTOGRAM_ZERO_SUPPRESSION_FILL
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
void
|
void
|
||||||
zero_suppression_decode(char* output, std::size_t output_len,
|
zero_suppression_decode(T* output, uintptr_t size,
|
||||||
const std::vector<char>& input);
|
const std::vector<T>& input)
|
||||||
|
{
|
||||||
|
const T* inp = &input[0];
|
||||||
|
const T* output_end = output + size;
|
||||||
|
while (output != output_end) {
|
||||||
|
*output = *inp;
|
||||||
|
if (*inp == 0) {
|
||||||
|
const uintptr_t nzero = *(++inp);
|
||||||
|
for (T j = 1; j != nzero; ++j) {
|
||||||
|
*(++output) = 0;
|
||||||
|
if (output == output_end)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++inp;
|
||||||
|
++output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void
|
||||||
|
zero_suppression_decode(wtype* output, uintptr_t size,
|
||||||
|
const std::vector<wtype>& input);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
bool
|
||||||
|
zero_suppression_encode(std::vector<wtype>& output, const wtype* input,
|
||||||
|
uintptr_t size);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef _BOOST_HISTOGRAM_NHISTOGRAM_HPP_
|
#ifndef _BOOST_HISTOGRAM_HISTOGRAM_HPP_
|
||||||
#define _BOOST_HISTOGRAM_NHISTOGRAM_HPP_
|
#define _BOOST_HISTOGRAM_HISTOGRAM_HPP_
|
||||||
|
|
||||||
#include <boost/histogram/axis.hpp>
|
#include <boost/histogram/axis.hpp>
|
||||||
#include <boost/histogram/histogram_base.hpp>
|
#include <boost/histogram/histogram_base.hpp>
|
||||||
@ -9,28 +9,27 @@
|
|||||||
#include <boost/serialization/base_object.hpp>
|
#include <boost/serialization/base_object.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/assert.hpp>
|
#include <boost/assert.hpp>
|
||||||
#include <boost/python/dict.hpp>
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace histogram {
|
namespace histogram {
|
||||||
|
|
||||||
class nhistogram : public histogram_base {
|
class histogram : public histogram_base {
|
||||||
public:
|
public:
|
||||||
nhistogram() {}
|
histogram() {}
|
||||||
|
|
||||||
nhistogram(const nhistogram& o) :
|
histogram(const histogram& o) :
|
||||||
histogram_base(o),
|
histogram_base(o),
|
||||||
data_(o.data_)
|
data_(o.data_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
explicit
|
explicit
|
||||||
nhistogram(const axes_type& axes) :
|
histogram(const axes_type& axes) :
|
||||||
histogram_base(axes),
|
histogram_base(axes),
|
||||||
data_(field_count())
|
data_(field_count())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#define BOOST_NHISTOGRAM_CTOR(z, n, unused) \
|
#define BOOST_NHISTOGRAM_CTOR(z, n, unused) \
|
||||||
nhistogram( BOOST_PP_ENUM_PARAMS_Z(z, n, const axis_type& a) ) : \
|
histogram( BOOST_PP_ENUM_PARAMS_Z(z, n, const axis_type& a) ) : \
|
||||||
histogram_base( BOOST_PP_ENUM_PARAMS_Z(z, n, a) ), \
|
histogram_base( BOOST_PP_ENUM_PARAMS_Z(z, n, a) ), \
|
||||||
data_(field_count()) \
|
data_(field_count()) \
|
||||||
{}
|
{}
|
||||||
@ -73,12 +72,43 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_CTOR, ni
|
|||||||
// generates fill functions taking 1 to AXIS_LIMT arguments
|
// generates fill functions taking 1 to AXIS_LIMT arguments
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_FILL, nil)
|
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_FILL, nil)
|
||||||
|
|
||||||
|
template <typename Container>
|
||||||
|
inline
|
||||||
|
void wfill(const Container& v, double w)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(v.size() == dim());
|
||||||
|
const size_type k = pos(v);
|
||||||
|
if (k != uintmax_t(-1))
|
||||||
|
data_.increase(k, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
// C-style call
|
||||||
|
inline
|
||||||
|
void wfill(unsigned n, const double* v, double w)
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(n == dim());
|
||||||
|
const size_type k = pos(v);
|
||||||
|
if (k != uintmax_t(-1))
|
||||||
|
data_.increase(k, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_NHISTOGRAM_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(n, buffer, w); /* size is checked here */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
// generates wfill functions taking 1 to AXIS_LIMT arguments
|
||||||
|
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_WFILL, nil)
|
||||||
|
|
||||||
template <typename Container>
|
template <typename Container>
|
||||||
double value(const Container& idx)
|
double value(const Container& idx)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(idx.size() == dim());
|
BOOST_ASSERT(idx.size() == dim());
|
||||||
return data_.read(linearize(idx));
|
return data_.value(linearize(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
// C-style call
|
// C-style call
|
||||||
@ -86,7 +116,7 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_FILL, ni
|
|||||||
const
|
const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT(n == dim());
|
BOOST_ASSERT(n == dim());
|
||||||
return data_.read(linearize(idx));
|
return data_.value(linearize(idx));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BOOST_NHISTOGRAM_VALUE(z, n, unused) \
|
#define BOOST_NHISTOGRAM_VALUE(z, n, unused) \
|
||||||
@ -100,11 +130,38 @@ BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_FILL, ni
|
|||||||
// generates value functions taking 1 to AXIS_LIMT arguments
|
// generates value functions taking 1 to AXIS_LIMT arguments
|
||||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_VALUE, nil)
|
BOOST_PP_REPEAT_FROM_TO(1, BOOST_HISTOGRAM_AXIS_LIMIT, BOOST_NHISTOGRAM_VALUE, nil)
|
||||||
|
|
||||||
bool operator==(const nhistogram& o) const
|
template <typename Container>
|
||||||
|
double variance(const Container& idx)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(idx.size() == dim());
|
||||||
|
return data_.variance(linearize(idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
// C-style call
|
||||||
|
double variance(unsigned n, const int* idx)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
BOOST_ASSERT(n == dim());
|
||||||
|
return data_.variance(linearize(idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BOOST_NHISTOGRAM_VARIANCE(z, n, unused) \
|
||||||
|
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(n, 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_NHISTOGRAM_VARIANCE, nil)
|
||||||
|
|
||||||
|
bool operator==(const histogram& o) const
|
||||||
{ return histogram_base::operator==(o) &&
|
{ return histogram_base::operator==(o) &&
|
||||||
data_ == o.data_; }
|
data_ == o.data_; }
|
||||||
|
|
||||||
nhistogram& operator+=(const nhistogram& o)
|
histogram& operator+=(const histogram& o)
|
||||||
{ data_ += o.data_; return *this; }
|
{ data_ += o.data_; return *this; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -118,11 +175,11 @@ private:
|
|||||||
ar & data_;
|
ar & data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend python::dict nhistogram_array_interface(nhistogram&);
|
friend class buffer_access;
|
||||||
};
|
};
|
||||||
|
|
||||||
nhistogram operator+(const nhistogram& a, const nhistogram& b) {
|
histogram operator+(const histogram& a, const histogram& b) {
|
||||||
nhistogram result(a);
|
histogram result(a);
|
||||||
return result += b;
|
return result += b;
|
||||||
}
|
}
|
||||||
|
|
@ -1,110 +0,0 @@
|
|||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <boost/serialization/array.hpp>
|
|
||||||
|
|
||||||
class wstore {
|
|
||||||
public:
|
|
||||||
typedef boost::uintmax_t size_type;
|
|
||||||
struct wcount { double w_, w2_; };
|
|
||||||
|
|
||||||
private:
|
|
||||||
size_type size_;
|
|
||||||
double* buffer_;
|
|
||||||
|
|
||||||
friend class boost::serialization::access;
|
|
||||||
template <class Archive>
|
|
||||||
void serialize(Archive & ar, unsigned version) {
|
|
||||||
using boost::serialization::make_array;
|
|
||||||
size_type s = size_;
|
|
||||||
ar & make_nvp("size", size_);
|
|
||||||
if (s != size_) {
|
|
||||||
destroy();
|
|
||||||
create();
|
|
||||||
}
|
|
||||||
ar & make_nvp("data", \
|
|
||||||
make_array(buffer_, size_ * 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
create() {
|
|
||||||
buffer_ = (double*)std::calloc(size_, sizeof(wcount));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
destroy() {
|
|
||||||
free(buffer_);
|
|
||||||
buffer_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
wstore()
|
|
||||||
: size_(0), buffer_(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
wstore(size_type n)
|
|
||||||
: size_(n)
|
|
||||||
{
|
|
||||||
create();
|
|
||||||
}
|
|
||||||
|
|
||||||
wstore(const wstore& other)
|
|
||||||
: size_(other.size_)
|
|
||||||
{
|
|
||||||
create();
|
|
||||||
*this = other;
|
|
||||||
}
|
|
||||||
|
|
||||||
~wstore() { destroy(); }
|
|
||||||
|
|
||||||
wstore&
|
|
||||||
operator=(const wstore& other)
|
|
||||||
{
|
|
||||||
if (size_ != other.size_) {
|
|
||||||
destroy();
|
|
||||||
size_ = other.size_;
|
|
||||||
create();
|
|
||||||
}
|
|
||||||
std::memcpy(buffer_, other.buffer_, size_ * sizeof(wcount));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
wcount&
|
|
||||||
operator[](size_type i)
|
|
||||||
{
|
|
||||||
return *((wcount*)buffer_ + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
|
||||||
const wcount&
|
|
||||||
operator[](size_type i) const
|
|
||||||
{
|
|
||||||
return *((wcount*)buffer_ + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
wstore&
|
|
||||||
operator+=(const wstore& other) {
|
|
||||||
if (size_ != other.size_)
|
|
||||||
throw std::logic_error("sizes do not match");
|
|
||||||
|
|
||||||
for (size_type i = 0; i < (size_ * 2); ++i)
|
|
||||||
buffer_[i] += other.buffer_[i];
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
operator==(const wstore& other) const {
|
|
||||||
if (size_ != other.size_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (size_type i = 0; i < (size_ * 2); ++i)
|
|
||||||
if (buffer_[i] != other.buffer_[i])
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_type size() const { return size_; }
|
|
||||||
inline const double* buffer() const { return buffer_; }
|
|
||||||
};
|
|
@ -1,16 +1,16 @@
|
|||||||
#include <boost/histogram/nhistogram.hpp>
|
#include <boost/histogram/histogram.hpp>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace histogram {
|
namespace histogram {
|
||||||
|
|
||||||
double
|
double
|
||||||
nhistogram::sum()
|
histogram::sum()
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
double result = 0.0;
|
double result = 0.0;
|
||||||
for (size_type i = 0, n = field_count(); i < n; ++i)
|
for (size_type i = 0, n = field_count(); i < n; ++i)
|
||||||
result += data_.read(i);
|
result += data_.value(i);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
141
src/nstore.cpp
141
src/nstore.cpp
@ -50,8 +50,42 @@ nstore::operator+=(const nstore& o)
|
|||||||
{
|
{
|
||||||
if (size_ != o.size_)
|
if (size_ != o.size_)
|
||||||
throw std::logic_error("sizes do not match");
|
throw std::logic_error("sizes do not match");
|
||||||
for (size_type i = 0; i < size_; ++i)
|
|
||||||
write(i, read(i) + o.read(i));
|
if (depth_ != o.depth_) {
|
||||||
|
if (o.depth_ == sizeof(wtype))
|
||||||
|
wconvert();
|
||||||
|
else
|
||||||
|
while (depth_ < o.depth_)
|
||||||
|
grow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth_ == sizeof(wtype)) {
|
||||||
|
for (size_type i = 0; i < size_; ++i)
|
||||||
|
((wtype*)buffer_)[i] += ((wtype*)o.buffer_)[i];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
size_type i = 0;
|
||||||
|
while (i < size_) {
|
||||||
|
const uint64_t oi = o.ivalue(i);
|
||||||
|
switch (depth_) {
|
||||||
|
#define BOOST_HISTOGRAM_NSTORE_ADD(T) \
|
||||||
|
case sizeof(T): { \
|
||||||
|
T& b = ((T*)buffer_)[i]; \
|
||||||
|
if ((std::numeric_limits<T>::max() - b) >= oi) { \
|
||||||
|
b += oi; \
|
||||||
|
++i; \
|
||||||
|
break; \
|
||||||
|
} else grow(); /* add fall through */ \
|
||||||
|
}
|
||||||
|
BOOST_HISTOGRAM_NSTORE_ADD(uint8_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_ADD(uint16_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_ADD(uint32_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_ADD(uint64_t);
|
||||||
|
#undef BOOST_HISTOGRAM_NSTORE_ADD
|
||||||
|
default: assert(!"invalid depth");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,42 +98,31 @@ nstore::operator==(const nstore& o)
|
|||||||
return std::memcmp(buffer_, o.buffer_, size_ * depth_) == 0;
|
return std::memcmp(buffer_, o.buffer_, size_ * depth_) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
double
|
||||||
nstore::read(size_type i)
|
nstore::value(size_type i)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if (depth_ == sizeof(wtype))
|
||||||
|
return ((wtype*)buffer_)[i].w;
|
||||||
|
return ivalue(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
nstore::variance(size_type i)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
switch (depth_) {
|
switch (depth_) {
|
||||||
#define BOOST_HISTOGRAM_NSTORE_READ(T) \
|
case sizeof(wtype): return ((wtype*)buffer_)[i].w2;
|
||||||
|
#define BOOST_HISTOGRAM_NSTORE_VARIANCE(T) \
|
||||||
case sizeof(T): return ((T*)buffer_)[i]
|
case sizeof(T): return ((T*)buffer_)[i]
|
||||||
BOOST_HISTOGRAM_NSTORE_READ(uint8_t);
|
BOOST_HISTOGRAM_NSTORE_VARIANCE(uint8_t);
|
||||||
BOOST_HISTOGRAM_NSTORE_READ(uint16_t);
|
BOOST_HISTOGRAM_NSTORE_VARIANCE(uint16_t);
|
||||||
BOOST_HISTOGRAM_NSTORE_READ(uint32_t);
|
BOOST_HISTOGRAM_NSTORE_VARIANCE(uint32_t);
|
||||||
BOOST_HISTOGRAM_NSTORE_READ(uint64_t);
|
BOOST_HISTOGRAM_NSTORE_VARIANCE(uint64_t);
|
||||||
#undef BOOST_HISTOGRAM_NSTORE_READ
|
#undef BOOST_HISTOGRAM_NSTORE_VARIANCE
|
||||||
default: assert(!"invalid depth");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nstore::write(size_type i, uint64_t v)
|
|
||||||
{
|
|
||||||
const uint64_t vmax = max_count();
|
|
||||||
while (vmax < v) grow();
|
|
||||||
|
|
||||||
switch (depth_) {
|
|
||||||
#define BOOST_HISTOGRAM_NSTORE_WRITE(T) \
|
|
||||||
case sizeof(T): { \
|
|
||||||
((T*)buffer_)[i] = v; \
|
|
||||||
break; \
|
|
||||||
}
|
|
||||||
BOOST_HISTOGRAM_NSTORE_WRITE(uint8_t);
|
|
||||||
BOOST_HISTOGRAM_NSTORE_WRITE(uint16_t);
|
|
||||||
BOOST_HISTOGRAM_NSTORE_WRITE(uint32_t);
|
|
||||||
BOOST_HISTOGRAM_NSTORE_WRITE(uint64_t);
|
|
||||||
#undef BOOST_HISTOGRAM_NSTORE_WRITE
|
|
||||||
default: assert(!"invalid depth");
|
default: assert(!"invalid depth");
|
||||||
}
|
}
|
||||||
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -118,17 +141,17 @@ nstore::destroy()
|
|||||||
void
|
void
|
||||||
nstore::grow()
|
nstore::grow()
|
||||||
{
|
{
|
||||||
if (depth_ == sizeof(uint64_t))
|
assert(depth_ > 0);
|
||||||
throw std::overflow_error("depth > 64 bit is not supported");
|
assert(depth_ < sizeof(uint64_t));
|
||||||
if (depth_ == 0 || buffer_ == 0)
|
assert(buffer_ != 0);
|
||||||
throw std::logic_error("cannot call grow on null buffer");
|
|
||||||
buffer_ = std::realloc(buffer_, size_ * 2 * depth_);
|
buffer_ = std::realloc(buffer_, size_ * 2 * depth_);
|
||||||
if (!buffer_) throw std::bad_alloc();
|
if (!buffer_) throw std::bad_alloc();
|
||||||
|
size_type i = size_;
|
||||||
switch (depth_) {
|
switch (depth_) {
|
||||||
#define BOOST_HISTOGRAM_NSTORE_GROW(T0, T1) \
|
#define BOOST_HISTOGRAM_NSTORE_GROW(T0, T1) \
|
||||||
case sizeof(T0): \
|
case sizeof(T0): \
|
||||||
for (size_type i = size_ - 1; i != size_type(-1); --i) \
|
while (i--) \
|
||||||
((T1*)buffer_)[i] = ((T0*)buffer_)[i]; \
|
((T1*)buffer_)[i] = ((T0*)buffer_)[i]; \
|
||||||
break
|
break
|
||||||
BOOST_HISTOGRAM_NSTORE_GROW(uint8_t, uint16_t);
|
BOOST_HISTOGRAM_NSTORE_GROW(uint8_t, uint16_t);
|
||||||
BOOST_HISTOGRAM_NSTORE_GROW(uint16_t, uint32_t);
|
BOOST_HISTOGRAM_NSTORE_GROW(uint16_t, uint32_t);
|
||||||
@ -138,17 +161,41 @@ nstore::grow()
|
|||||||
depth_ *= 2;
|
depth_ *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nstore::wconvert()
|
||||||
|
{
|
||||||
|
assert(depth_ < sizeof(wtype));
|
||||||
|
buffer_ = std::realloc(buffer_, size_ * sizeof(wtype));
|
||||||
|
if (!buffer_) throw std::bad_alloc();
|
||||||
|
size_type i = size_;
|
||||||
|
switch (depth_) {
|
||||||
|
#define BOOST_HISTOGRAM_NSTORE_CONVERT(T) \
|
||||||
|
case sizeof(T): \
|
||||||
|
while (i--) \
|
||||||
|
((wtype*)buffer_)[i] = ((T*)buffer_)[i]; \
|
||||||
|
break
|
||||||
|
BOOST_HISTOGRAM_NSTORE_CONVERT(uint8_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_CONVERT(uint16_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_CONVERT(uint32_t);
|
||||||
|
BOOST_HISTOGRAM_NSTORE_CONVERT(uint64_t);
|
||||||
|
#undef BOOST_HISTOGRAM_NSTORE_CONVERT
|
||||||
|
default: break; // no nuthin'
|
||||||
|
}
|
||||||
|
depth_ = sizeof(wtype);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
nstore::max_count()
|
nstore::ivalue(size_type i)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
switch (depth_) {
|
switch (depth_) {
|
||||||
#define BOOST_HISTOGRAM_NSTORE_CASE(T) \
|
#define BOOST_HISTOGRAM_NSTORE_IVALUE(T) \
|
||||||
case sizeof(T): return std::numeric_limits<T>::max()
|
case sizeof(T): return ((T*)buffer_)[i]
|
||||||
BOOST_HISTOGRAM_NSTORE_CASE(uint8_t);
|
BOOST_HISTOGRAM_NSTORE_IVALUE(uint8_t);
|
||||||
BOOST_HISTOGRAM_NSTORE_CASE(uint16_t);
|
BOOST_HISTOGRAM_NSTORE_IVALUE(uint16_t);
|
||||||
BOOST_HISTOGRAM_NSTORE_CASE(uint32_t);
|
BOOST_HISTOGRAM_NSTORE_IVALUE(uint32_t);
|
||||||
BOOST_HISTOGRAM_NSTORE_CASE(uint64_t);
|
BOOST_HISTOGRAM_NSTORE_IVALUE(uint64_t);
|
||||||
|
#undef BOOST_HISTOGRAM_NSTORE_IVALUE
|
||||||
default: assert(!"invalid depth");
|
default: assert(!"invalid depth");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
|
#include "serialization_suite.hpp"
|
||||||
#include <boost/histogram/axis.hpp>
|
#include <boost/histogram/axis.hpp>
|
||||||
#include <boost/histogram/nhistogram.hpp>
|
#include <boost/histogram/histogram.hpp>
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
#include <boost/python/raw_function.hpp>
|
#include <boost/python/raw_function.hpp>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include "serialization_suite.hpp"
|
|
||||||
#ifdef USE_NUMPY
|
#ifdef USE_NUMPY
|
||||||
# define NO_IMPORT_ARRAY
|
# define NO_IMPORT_ARRAY
|
||||||
# define PY_ARRAY_UNIQUE_SYMBOL boost_histogram_ARRAY_API
|
# define PY_ARRAY_UNIQUE_SYMBOL boost_histogram_ARRAY_API
|
||||||
@ -16,7 +16,7 @@ namespace boost {
|
|||||||
namespace histogram {
|
namespace histogram {
|
||||||
|
|
||||||
python::object
|
python::object
|
||||||
nhistogram_init(python::tuple args, python::dict kwargs) {
|
histogram_init(python::tuple args, python::dict kwargs) {
|
||||||
using namespace python;
|
using namespace python;
|
||||||
using python::tuple;
|
using python::tuple;
|
||||||
|
|
||||||
@ -48,24 +48,12 @@ nhistogram_init(python::tuple args, python::dict kwargs) {
|
|||||||
return pyinit(axes);
|
return pyinit(axes);
|
||||||
}
|
}
|
||||||
|
|
||||||
python::dict
|
|
||||||
nhistogram_array_interface(nhistogram& self) {
|
|
||||||
python::list shape;
|
|
||||||
for (unsigned i = 0; i < self.dim(); ++i)
|
|
||||||
shape.append(self.shape(i));
|
|
||||||
python::dict d;
|
|
||||||
d["shape"] = python::tuple(shape);
|
|
||||||
d["typestr"] = python::str("<u") + python::str(self.depth());
|
|
||||||
d["data"] = python::make_tuple((long long)(self.data_.buffer()), false);
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
python::object
|
python::object
|
||||||
nhistogram_fill(python::tuple args, python::dict kwargs) {
|
histogram_fill(python::tuple args, python::dict kwargs) {
|
||||||
using namespace python;
|
using namespace python;
|
||||||
|
|
||||||
const unsigned nargs = len(args);
|
const unsigned nargs = len(args);
|
||||||
nhistogram& self = extract<nhistogram&>(args[0]);
|
histogram& self = extract<histogram&>(args[0]);
|
||||||
|
|
||||||
#ifdef USE_NUMPY
|
#ifdef USE_NUMPY
|
||||||
if (nargs == 2) {
|
if (nargs == 2) {
|
||||||
@ -128,7 +116,7 @@ nhistogram_fill(python::tuple args, python::dict kwargs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
nhistogram_getitem(const nhistogram& self, python::object oidx) {
|
histogram_getitem(const histogram& self, python::object oidx) {
|
||||||
using namespace python;
|
using namespace python;
|
||||||
|
|
||||||
if (self.dim() == 1)
|
if (self.dim() == 1)
|
||||||
@ -147,26 +135,42 @@ nhistogram_getitem(const nhistogram& self, python::object oidx) {
|
|||||||
return self.value(self.dim(), idx);
|
return self.value(self.dim(), idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_nhistogram()
|
class buffer_access {
|
||||||
|
public:
|
||||||
|
static
|
||||||
|
python::dict
|
||||||
|
histogram_array_interface(histogram& self) {
|
||||||
|
python::list shape;
|
||||||
|
for (unsigned i = 0; i < self.dim(); ++i)
|
||||||
|
shape.append(self.shape(i));
|
||||||
|
python::dict d;
|
||||||
|
d["shape"] = python::tuple(shape);
|
||||||
|
d["typestr"] = python::str("<u") + python::str(self.data_.depth());
|
||||||
|
d["data"] = python::make_tuple((long long)(self.data_.buffer()), false);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void register_histogram()
|
||||||
{
|
{
|
||||||
using namespace python;
|
using namespace python;
|
||||||
|
|
||||||
class_<
|
class_<
|
||||||
nhistogram, bases<histogram_base>,
|
histogram, bases<histogram_base>,
|
||||||
shared_ptr<nhistogram>
|
shared_ptr<histogram>
|
||||||
>("nhistogram", no_init)
|
>("histogram", no_init)
|
||||||
.def("__init__", raw_function(nhistogram_init))
|
.def("__init__", raw_function(histogram_init))
|
||||||
// shadowed C++ ctors
|
// shadowed C++ ctors
|
||||||
.def(init<const axes_type&>())
|
.def(init<const axes_type&>())
|
||||||
.add_property("__array_interface__", nhistogram_array_interface)
|
.add_property("__array_interface__", &buffer_access::histogram_array_interface)
|
||||||
.def("fill", raw_function(nhistogram_fill))
|
.def("fill", raw_function(histogram_fill))
|
||||||
.add_property("depth", &nhistogram::depth)
|
.add_property("depth", &histogram::depth)
|
||||||
.add_property("sum", &nhistogram::sum)
|
.add_property("sum", &histogram::sum)
|
||||||
.def("__getitem__", nhistogram_getitem)
|
.def("__getitem__", histogram_getitem)
|
||||||
.def(self == self)
|
.def(self == self)
|
||||||
.def(self += self)
|
.def(self += self)
|
||||||
.def(self + self)
|
.def(self + self)
|
||||||
.def_pickle(serialization_suite<nhistogram>())
|
.def_pickle(serialization_suite<histogram>())
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
@ -8,7 +8,7 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace histogram {
|
namespace histogram {
|
||||||
void register_histogram_base();
|
void register_histogram_base();
|
||||||
void register_nhistogram();
|
void register_histogram();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,5 +18,5 @@ BOOST_PYTHON_MODULE(histogram)
|
|||||||
import_array();
|
import_array();
|
||||||
#endif
|
#endif
|
||||||
boost::histogram::register_histogram_base();
|
boost::histogram::register_histogram_base();
|
||||||
boost::histogram::register_nhistogram();
|
boost::histogram::register_histogram();
|
||||||
}
|
}
|
||||||
|
@ -4,50 +4,52 @@ namespace boost {
|
|||||||
namespace histogram {
|
namespace histogram {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
template <>
|
||||||
bool
|
bool
|
||||||
zero_suppression_encode(std::vector<char>& output, std::size_t output_max,
|
zero_suppression_encode(std::vector<wtype>& output, const wtype* input,
|
||||||
const char* input, std::size_t input_len)
|
uintptr_t size)
|
||||||
{
|
{
|
||||||
#define FILL_OUTPUT { \
|
#define BOOST_HISTOGRAM_ZERO_SUPPRESSION_FILL { \
|
||||||
if ((output_max - output.size()) < 2) \
|
if ((size - output.size()) < 2) \
|
||||||
return false; \
|
return false; \
|
||||||
output.push_back(0); \
|
output.push_back(0); \
|
||||||
output.push_back(nzero); \
|
output.push_back(nzero); \
|
||||||
nzero = 0; \
|
nzero = 0; \
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* input_end = input + input_len;
|
const wtype* input_end = input + size;
|
||||||
unsigned nzero = 0;
|
uint32_t nzero = 0;
|
||||||
for (; input != input_end; ++input) {
|
for (; input != input_end; ++input) {
|
||||||
if (*input != 0) {
|
if (*input != 0) {
|
||||||
if (nzero)
|
if (nzero)
|
||||||
FILL_OUTPUT
|
BOOST_HISTOGRAM_ZERO_SUPPRESSION_FILL
|
||||||
if (output.size() == output_max)
|
if (output.size() == size)
|
||||||
return false;
|
return false;
|
||||||
output.push_back(*input);
|
output.push_back(*input);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
++nzero;
|
++nzero;
|
||||||
if (nzero == 256)
|
if (nzero == 0) // overflowed to zero
|
||||||
FILL_OUTPUT
|
BOOST_HISTOGRAM_ZERO_SUPPRESSION_FILL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nzero)
|
if (nzero)
|
||||||
FILL_OUTPUT
|
BOOST_HISTOGRAM_ZERO_SUPPRESSION_FILL
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
void
|
void
|
||||||
zero_suppression_decode(char* output, std::size_t output_len,
|
zero_suppression_decode(wtype* output, uintptr_t size,
|
||||||
const std::vector<char>& input)
|
const std::vector<wtype>& input)
|
||||||
{
|
{
|
||||||
const char* inp = &input[0];
|
const wtype* inp = &input[0];
|
||||||
const char* output_end = output + output_len;
|
const wtype* output_end = output + size;
|
||||||
while (output != output_end) {
|
while (output != output_end) {
|
||||||
*output = *inp;
|
*output = *inp;
|
||||||
if (*inp == 0) {
|
if (*inp == 0) {
|
||||||
const char nzero = *(++inp);
|
const uintptr_t nzero = (++inp)->w;
|
||||||
for (char j = 1; j != nzero; ++j) {
|
for (uintptr_t j = 1; j != nzero; ++j) {
|
||||||
*(++output) = 0;
|
*(++output) = 0;
|
||||||
if (output == output_end)
|
if (output == output_end)
|
||||||
return;
|
return;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import unittest
|
import unittest
|
||||||
from math import pi
|
from math import pi
|
||||||
from histogram import nhistogram, regular_axis, polar_axis, \
|
from histogram import histogram, regular_axis, polar_axis, \
|
||||||
variable_axis, category_axis, integer_axis
|
variable_axis, category_axis, integer_axis
|
||||||
import cPickle
|
import cPickle
|
||||||
import StringIO
|
import StringIO
|
||||||
@ -299,39 +299,39 @@ class test_integer_axis(unittest.TestCase):
|
|||||||
self.assertEqual(a.index(3), 4)
|
self.assertEqual(a.index(3), 4)
|
||||||
self.assertEqual(a.index(4), 4)
|
self.assertEqual(a.index(4), 4)
|
||||||
|
|
||||||
class nhistogram_test(unittest.TestCase):
|
class histogram_test(unittest.TestCase):
|
||||||
|
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
nhistogram(integer_axis(-1, 1))
|
histogram(integer_axis(-1, 1))
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
nhistogram(1)
|
histogram(1)
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
nhistogram("bla")
|
histogram("bla")
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
nhistogram([])
|
histogram([])
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
nhistogram(regular_axis)
|
histogram(regular_axis)
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
nhistogram(regular_axis())
|
histogram(regular_axis())
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
nhistogram([integer_axis(-1, 1)])
|
histogram([integer_axis(-1, 1)])
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
nhistogram(integer_axis(-1, 1), unknown_keyword="nh")
|
histogram(integer_axis(-1, 1), unknown_keyword="nh")
|
||||||
|
|
||||||
h = nhistogram(integer_axis(-1, 1))
|
h = histogram(integer_axis(-1, 1))
|
||||||
self.assertEqual(h.dim, 1)
|
self.assertEqual(h.dim, 1)
|
||||||
self.assertEqual(h.axis(0), integer_axis(-1, 1))
|
self.assertEqual(h.axis(0), integer_axis(-1, 1))
|
||||||
self.assertEqual(h.shape(0), 5)
|
self.assertEqual(h.shape(0), 5)
|
||||||
self.assertEqual(h.depth, 1)
|
self.assertEqual(h.depth, 1)
|
||||||
self.assertEqual(nhistogram(integer_axis(-1, 1, uoflow=False)).shape(0), 3)
|
self.assertEqual(histogram(integer_axis(-1, 1, uoflow=False)).shape(0), 3)
|
||||||
self.assertNotEqual(h, nhistogram(regular_axis(1, -1, 1)))
|
self.assertNotEqual(h, histogram(regular_axis(1, -1, 1)))
|
||||||
self.assertNotEqual(h, nhistogram(integer_axis(-1, 2)))
|
self.assertNotEqual(h, histogram(integer_axis(-1, 2)))
|
||||||
self.assertNotEqual(h, nhistogram(integer_axis(-1, 1, label="ia")))
|
self.assertNotEqual(h, histogram(integer_axis(-1, 1, label="ia")))
|
||||||
self.assertNotEqual(h, nhistogram(integer_axis(-1, 1, uoflow=True)))
|
self.assertNotEqual(h, histogram(integer_axis(-1, 1, uoflow=True)))
|
||||||
|
|
||||||
def test_fill_1d(self):
|
def test_fill_1d(self):
|
||||||
h0 = nhistogram(integer_axis(-1, 1, uoflow=False))
|
h0 = histogram(integer_axis(-1, 1, uoflow=False))
|
||||||
h1 = nhistogram(integer_axis(-1, 1, uoflow=True))
|
h1 = histogram(integer_axis(-1, 1, uoflow=True))
|
||||||
for h in (h0, h1):
|
for h in (h0, h1):
|
||||||
with self.assertRaises(StandardError):
|
with self.assertRaises(StandardError):
|
||||||
h.fill()
|
h.fill()
|
||||||
@ -363,7 +363,7 @@ class nhistogram_test(unittest.TestCase):
|
|||||||
self.assertEqual(h1[3], 1)
|
self.assertEqual(h1[3], 1)
|
||||||
|
|
||||||
def test_growth(self):
|
def test_growth(self):
|
||||||
h = nhistogram(integer_axis(-1, 1))
|
h = histogram(integer_axis(-1, 1))
|
||||||
h.fill(-1)
|
h.fill(-1)
|
||||||
h.fill(1)
|
h.fill(1)
|
||||||
h.fill(1)
|
h.fill(1)
|
||||||
@ -382,7 +382,7 @@ class nhistogram_test(unittest.TestCase):
|
|||||||
|
|
||||||
def test_fill_2d(self):
|
def test_fill_2d(self):
|
||||||
for uoflow in (False, True):
|
for uoflow in (False, True):
|
||||||
h = nhistogram(integer_axis(-1, 1, uoflow=uoflow),
|
h = histogram(integer_axis(-1, 1, uoflow=uoflow),
|
||||||
regular_axis(4, -2, 2, uoflow=uoflow))
|
regular_axis(4, -2, 2, uoflow=uoflow))
|
||||||
h.fill(-1, -2)
|
h.fill(-1, -2)
|
||||||
h.fill(-1, -1)
|
h.fill(-1, -1)
|
||||||
@ -407,7 +407,7 @@ class nhistogram_test(unittest.TestCase):
|
|||||||
|
|
||||||
def test_add_2d(self):
|
def test_add_2d(self):
|
||||||
for uoflow in (False, True):
|
for uoflow in (False, True):
|
||||||
h = nhistogram(integer_axis(-1, 1, uoflow=uoflow),
|
h = histogram(integer_axis(-1, 1, uoflow=uoflow),
|
||||||
regular_axis(4, -2, 2, uoflow=uoflow))
|
regular_axis(4, -2, 2, uoflow=uoflow))
|
||||||
h.fill(-1, -2)
|
h.fill(-1, -2)
|
||||||
h.fill(-1, -1)
|
h.fill(-1, -1)
|
||||||
@ -432,7 +432,7 @@ class nhistogram_test(unittest.TestCase):
|
|||||||
self.assertEqual(h[i, j], 2 * m[i][j])
|
self.assertEqual(h[i, j], 2 * m[i][j])
|
||||||
|
|
||||||
def test_pickle(self):
|
def test_pickle(self):
|
||||||
a = nhistogram(category_axis('A', 'B', 'C'),
|
a = histogram(category_axis('A', 'B', 'C'),
|
||||||
integer_axis(0, 3, label='ia'),
|
integer_axis(0, 3, label='ia'),
|
||||||
regular_axis(4, 0.0, 4.0, uoflow=False),
|
regular_axis(4, 0.0, 4.0, uoflow=False),
|
||||||
variable_axis(0.0, 1.0, 2.0))
|
variable_axis(0.0, 1.0, 2.0))
|
||||||
@ -460,7 +460,7 @@ class nhistogram_test(unittest.TestCase):
|
|||||||
|
|
||||||
@unittest.skipUnless("numpy" in globals(), "requires numpy")
|
@unittest.skipUnless("numpy" in globals(), "requires numpy")
|
||||||
def test_numpy_conversion(self):
|
def test_numpy_conversion(self):
|
||||||
a = nhistogram(integer_axis(0, 2, uoflow=False))
|
a = histogram(integer_axis(0, 2, uoflow=False))
|
||||||
for i in xrange(100):
|
for i in xrange(100):
|
||||||
a.fill(1)
|
a.fill(1)
|
||||||
b = numpy.array(a) # a copy
|
b = numpy.array(a) # a copy
|
||||||
@ -481,19 +481,19 @@ class nhistogram_test(unittest.TestCase):
|
|||||||
|
|
||||||
@unittest.skipUnless("numpy" in globals(), "requires numpy")
|
@unittest.skipUnless("numpy" in globals(), "requires numpy")
|
||||||
def test_fill_with_numpy_array(self):
|
def test_fill_with_numpy_array(self):
|
||||||
a = nhistogram(integer_axis(0, 2, uoflow=False))
|
a = histogram(integer_axis(0, 2, uoflow=False))
|
||||||
a.fill(numpy.array([-1, 0, 1, 2, 1, 4]))
|
a.fill(numpy.array([-1, 0, 1, 2, 1, 4]))
|
||||||
self.assertEqual(a[0], 1)
|
self.assertEqual(a[0], 1)
|
||||||
self.assertEqual(a[1], 2)
|
self.assertEqual(a[1], 2)
|
||||||
self.assertEqual(a[2], 1)
|
self.assertEqual(a[2], 1)
|
||||||
a = nhistogram(integer_axis(0, 1, uoflow=False),
|
a = histogram(integer_axis(0, 1, uoflow=False),
|
||||||
regular_axis(2, 0, 2, uoflow=False))
|
regular_axis(2, 0, 2, uoflow=False))
|
||||||
a.fill(numpy.array([[-1., -1.], [0., 1.], [1., 0.1]]))
|
a.fill(numpy.array([[-1., -1.], [0., 1.], [1., 0.1]]))
|
||||||
self.assertEqual(a[0, 0], 0)
|
self.assertEqual(a[0, 0], 0)
|
||||||
self.assertEqual(a[0, 1], 1)
|
self.assertEqual(a[0, 1], 1)
|
||||||
self.assertEqual(a[1, 0], 1)
|
self.assertEqual(a[1, 0], 1)
|
||||||
self.assertEqual(a[1, 1], 0)
|
self.assertEqual(a[1, 1], 0)
|
||||||
a = nhistogram(integer_axis(0, 2, uoflow=False))
|
a = histogram(integer_axis(0, 2, uoflow=False))
|
||||||
a.fill([0, 0, 1, 2])
|
a.fill([0, 0, 1, 2])
|
||||||
a.fill((1, 0, 2, 2))
|
a.fill((1, 0, 2, 2))
|
||||||
self.assertEqual(a[0], 3)
|
self.assertEqual(a[0], 3)
|
||||||
|
@ -5,150 +5,278 @@
|
|||||||
#include <boost/assign/std/vector.hpp>
|
#include <boost/assign/std/vector.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace boost::assign;
|
using namespace boost::assign;
|
||||||
using boost::histogram::detail::zero_suppression_encode;
|
using namespace boost::histogram::detail;
|
||||||
using boost::histogram::detail::zero_suppression_decode;
|
|
||||||
namespace tt = boost::test_tools;
|
namespace tt = boost::test_tools;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
void
|
void
|
||||||
print(const std::vector<char>& v) {
|
print(const std::vector<T>& v) {
|
||||||
std::cerr << "[";
|
std::cerr << "[";
|
||||||
for (unsigned i = 0; i < v.size(); ++i) {
|
for (unsigned i = 0; i < v.size(); ++i) {
|
||||||
std::cerr << unsigned(v[i]) << (i < v.size() - 1 ? ", " : "]");
|
std::cerr << v[i] << (i < v.size() - 1 ? ", " : "]");
|
||||||
}
|
}
|
||||||
std::cerr << "\n";
|
std::cerr << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EQUAL_VECTORS(a, b) \
|
#define EQUAL_VECTORS(a, b) BOOST_CHECK_EQUAL_COLLECTIONS(a.begin(), a.end(), b.begin(), b.end())
|
||||||
BOOST_CHECK_EQUAL_COLLECTIONS(a.begin(), a.end(), b.begin(), b.end())
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_no_zero )
|
BOOST_AUTO_TEST_CASE( codec_no_zero )
|
||||||
{
|
{
|
||||||
std::vector<char> a, b, c(3, 0);
|
std::vector<unsigned> a, b, c(3, 0);
|
||||||
a += 1, 1, 1;
|
a += 1, 1, 1;
|
||||||
BOOST_CHECK(zero_suppression_encode(b, 3, &a[0], a.size()));
|
BOOST_CHECK(zero_suppression_encode<unsigned>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(a, b);
|
EQUAL_VECTORS(a, b);
|
||||||
zero_suppression_decode(&c[0], c.size(), b);
|
zero_suppression_decode<unsigned>(&c[0], c.size(), b);
|
||||||
EQUAL_VECTORS(a, c);
|
EQUAL_VECTORS(a, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_fail )
|
|
||||||
{
|
|
||||||
std::vector<char> a, b;
|
|
||||||
a += 1, 1, 1;
|
|
||||||
BOOST_CHECK(zero_suppression_encode(b, 2, &a[0], a.size()) == false);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_empty )
|
BOOST_AUTO_TEST_CASE( codec_empty )
|
||||||
{
|
{
|
||||||
std::vector<char> a, b, c;
|
std::vector<unsigned> a, b, c;
|
||||||
BOOST_CHECK(zero_suppression_encode(b, 3, &a[0], a.size()));
|
BOOST_CHECK(zero_suppression_encode<unsigned>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(a, b);
|
EQUAL_VECTORS(a, b);
|
||||||
zero_suppression_decode(&c[0], c.size(), b);
|
zero_suppression_decode<unsigned>(&c[0], c.size(), b);
|
||||||
EQUAL_VECTORS(a, c);
|
EQUAL_VECTORS(a, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_zero_0 )
|
BOOST_AUTO_TEST_CASE( codec_zero_0a )
|
||||||
{
|
{
|
||||||
std::vector<char> a, b, c, d(2, 0);
|
std::vector<uint8_t> a, b;
|
||||||
a += 0, 1;
|
a += 0;
|
||||||
c += 0, 1, 1;
|
BOOST_CHECK(zero_suppression_encode<uint8_t>(b, &a[0], a.size()) == false);
|
||||||
BOOST_CHECK(zero_suppression_encode(b, c.size(), &a[0], a.size()));
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_1a )
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> a, b, c, d(3, 0);
|
||||||
|
a += 1, 0, 0;
|
||||||
|
c += 1, 0, 2;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<uint8_t>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(b, c);
|
EQUAL_VECTORS(b, c);
|
||||||
zero_suppression_decode(&d[0], d.size(), b);
|
zero_suppression_decode<uint8_t>(&d[0], d.size(), b);
|
||||||
EQUAL_VECTORS(a, d);
|
EQUAL_VECTORS(a, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_zero_1 )
|
BOOST_AUTO_TEST_CASE( codec_zero_2a )
|
||||||
{
|
{
|
||||||
std::vector<char> a, b, c, d(3, 0);
|
std::vector<uint8_t> a, b, c, d(3, 0);
|
||||||
a += 0, 0, 1;
|
a += 0, 0, 1;
|
||||||
c += 0, 2, 1;
|
c += 0, 2, 1;
|
||||||
BOOST_CHECK(zero_suppression_encode(b, c.size(), &a[0], a.size()));
|
BOOST_CHECK(zero_suppression_encode<uint8_t>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(b, c);
|
EQUAL_VECTORS(b, c);
|
||||||
zero_suppression_decode(&d[0], d.size(), b);
|
zero_suppression_decode<uint8_t>(&d[0], d.size(), b);
|
||||||
EQUAL_VECTORS(a, d);
|
EQUAL_VECTORS(a, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_zero_2 )
|
BOOST_AUTO_TEST_CASE( codec_zero_3a )
|
||||||
{
|
{
|
||||||
std::vector<char> a, b, c, d(2, 0);
|
std::vector<uint8_t> a, b, c, d(2, 0);
|
||||||
a += 0, 0;
|
a += 0, 0;
|
||||||
c += 0, 2;
|
c += 0, 2;
|
||||||
BOOST_CHECK(zero_suppression_encode(b, c.size(), &a[0], a.size()));
|
BOOST_CHECK(zero_suppression_encode<uint8_t>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(b, c);
|
EQUAL_VECTORS(b, c);
|
||||||
zero_suppression_decode(&d[0], d.size(), b);
|
zero_suppression_decode<uint8_t>(&d[0], d.size(), b);
|
||||||
EQUAL_VECTORS(a, d);
|
EQUAL_VECTORS(a, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_zero_3 )
|
BOOST_AUTO_TEST_CASE( codec_zero_0b )
|
||||||
{
|
{
|
||||||
std::vector<char> a, b, c, d(1, 0);
|
std::vector<unsigned> a, b;
|
||||||
a += 0;
|
a += 0;
|
||||||
c += 0, 1;
|
BOOST_CHECK(zero_suppression_encode<unsigned>(b, &a[0], a.size()) == false);
|
||||||
BOOST_CHECK(zero_suppression_encode(b, c.size(), &a[0], a.size()));
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_1b )
|
||||||
|
{
|
||||||
|
std::vector<unsigned> a, b, c, d(3, 0);
|
||||||
|
a += 1, 0, 0;
|
||||||
|
c += 1, 0, 2;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<unsigned>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(b, c);
|
EQUAL_VECTORS(b, c);
|
||||||
zero_suppression_decode(&d[0], d.size(), b);
|
zero_suppression_decode<unsigned>(&d[0], d.size(), b);
|
||||||
|
EQUAL_VECTORS(a, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_2b )
|
||||||
|
{
|
||||||
|
std::vector<unsigned> a, b, c, d(3, 0);
|
||||||
|
a += 0, 0, 1;
|
||||||
|
c += 0, 2, 1;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<unsigned>(b, &a[0], a.size()));
|
||||||
|
EQUAL_VECTORS(b, c);
|
||||||
|
zero_suppression_decode<unsigned>(&d[0], d.size(), b);
|
||||||
|
EQUAL_VECTORS(a, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_3b )
|
||||||
|
{
|
||||||
|
std::vector<unsigned> a, b, c, d(2, 0);
|
||||||
|
a += 0, 0;
|
||||||
|
c += 0, 2;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<unsigned>(b, &a[0], a.size()));
|
||||||
|
EQUAL_VECTORS(b, c);
|
||||||
|
zero_suppression_decode<unsigned>(&d[0], d.size(), b);
|
||||||
|
EQUAL_VECTORS(a, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_0c )
|
||||||
|
{
|
||||||
|
std::vector<uint64_t> a, b;
|
||||||
|
a += 0;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<uint64_t>(b, &a[0], a.size()) == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_1c )
|
||||||
|
{
|
||||||
|
std::vector<uint64_t> a, b, c, d(3, 0);
|
||||||
|
a += 1, 0, 0;
|
||||||
|
c += 1, 0, 2;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<uint64_t>(b, &a[0], a.size()));
|
||||||
|
EQUAL_VECTORS(b, c);
|
||||||
|
zero_suppression_decode<uint64_t>(&d[0], d.size(), b);
|
||||||
|
EQUAL_VECTORS(a, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_2c )
|
||||||
|
{
|
||||||
|
std::vector<uint64_t> a, b, c, d(3, 0);
|
||||||
|
a += 0, 0, 1;
|
||||||
|
c += 0, 2, 1;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<uint64_t>(b, &a[0], a.size()));
|
||||||
|
EQUAL_VECTORS(b, c);
|
||||||
|
zero_suppression_decode<uint64_t>(&d[0], d.size(), b);
|
||||||
|
EQUAL_VECTORS(a, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_3c )
|
||||||
|
{
|
||||||
|
std::vector<uint64_t> a, b, c, d(2, 0);
|
||||||
|
a += 0, 0;
|
||||||
|
c += 0, 2;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<uint64_t>(b, &a[0], a.size()));
|
||||||
|
EQUAL_VECTORS(b, c);
|
||||||
|
zero_suppression_decode<uint64_t>(&d[0], d.size(), b);
|
||||||
|
EQUAL_VECTORS(a, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_0d )
|
||||||
|
{
|
||||||
|
std::vector<wtype> a, b;
|
||||||
|
a += 0;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<wtype>(b, &a[0], a.size()) == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_1d )
|
||||||
|
{
|
||||||
|
std::vector<wtype> a, b, c, d(3, 0);
|
||||||
|
a += 1, 0, 0;
|
||||||
|
c += 1, 0, 2;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<wtype>(b, &a[0], a.size()));
|
||||||
|
EQUAL_VECTORS(b, c);
|
||||||
|
zero_suppression_decode<wtype>(&d[0], d.size(), b);
|
||||||
|
EQUAL_VECTORS(a, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_2d )
|
||||||
|
{
|
||||||
|
std::vector<wtype> a, b, c, d(3, 0);
|
||||||
|
a += 0, 0, 1;
|
||||||
|
c += 0, 2, 1;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<wtype>(b, &a[0], a.size()));
|
||||||
|
EQUAL_VECTORS(b, c);
|
||||||
|
zero_suppression_decode<wtype>(&d[0], d.size(), b);
|
||||||
|
EQUAL_VECTORS(a, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_3d )
|
||||||
|
{
|
||||||
|
std::vector<wtype> a, b, c, d(2, 0);
|
||||||
|
a += 0, 0;
|
||||||
|
c += 0, 2;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<wtype>(b, &a[0], a.size()));
|
||||||
|
EQUAL_VECTORS(b, c);
|
||||||
|
zero_suppression_decode<wtype>(&d[0], d.size(), b);
|
||||||
EQUAL_VECTORS(a, d);
|
EQUAL_VECTORS(a, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_zero_4 )
|
BOOST_AUTO_TEST_CASE( codec_zero_4 )
|
||||||
{
|
{
|
||||||
std::vector<char> a, b, c, d(3, 0);
|
std::vector<unsigned> a, b, c, d(5, 0);
|
||||||
a += 0, 1, 0;
|
a += 0, 0, 0, 1, 0;
|
||||||
c += 0, 1, 1, 0, 1;
|
c += 0, 3, 1, 0, 1;
|
||||||
BOOST_CHECK(zero_suppression_encode(b, c.size(), &a[0], a.size()));
|
BOOST_CHECK(zero_suppression_encode<unsigned>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(b, c);
|
EQUAL_VECTORS(b, c);
|
||||||
zero_suppression_decode(&d[0], d.size(), b);
|
zero_suppression_decode<unsigned>(&d[0], d.size(), b);
|
||||||
EQUAL_VECTORS(a, d);
|
EQUAL_VECTORS(a, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_zero_5 )
|
BOOST_AUTO_TEST_CASE( codec_zero_5 )
|
||||||
{
|
{
|
||||||
std::vector<char> a, b, c, d(4, 0);
|
std::vector<unsigned> a, b, c, d(5, 0);
|
||||||
a += 0, 1, 0, 0;
|
a += 0, 1, 0, 0, 0;
|
||||||
c += 0, 1, 1, 0, 2;
|
c += 0, 1, 1, 0, 3;
|
||||||
BOOST_CHECK(zero_suppression_encode(b, c.size(), &a[0], a.size()));
|
BOOST_CHECK(zero_suppression_encode<unsigned>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(b, c);
|
EQUAL_VECTORS(b, c);
|
||||||
zero_suppression_decode(&d[0], d.size(), b);
|
zero_suppression_decode<unsigned>(&d[0], d.size(), b);
|
||||||
EQUAL_VECTORS(a, d);
|
EQUAL_VECTORS(a, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_zero_6 )
|
BOOST_AUTO_TEST_CASE( codec_zero_6 )
|
||||||
{
|
{
|
||||||
std::vector<char> a(255, 0), b, c, d(255, 0);
|
std::vector<uint8_t> a(255, 0), b, c, d(255, 0);
|
||||||
c += 0, 255;
|
c += 0, 255;
|
||||||
BOOST_CHECK(zero_suppression_encode(b, c.size(), &a[0], a.size()));
|
BOOST_CHECK(zero_suppression_encode<uint8_t>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(b, c);
|
EQUAL_VECTORS(b, c);
|
||||||
zero_suppression_decode(&d[0], d.size(), b);
|
zero_suppression_decode<uint8_t>(&d[0], d.size(), b);
|
||||||
EQUAL_VECTORS(a, d);
|
EQUAL_VECTORS(a, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_zero_7 )
|
BOOST_AUTO_TEST_CASE( codec_zero_7 )
|
||||||
{
|
{
|
||||||
std::vector<char> a(256, 0), b, c, d(256, 0);
|
std::vector<uint8_t> a(256, 0), b, c, d(256, 0);
|
||||||
c += 0, 0;
|
c += 0, 0;
|
||||||
BOOST_CHECK(zero_suppression_encode(b, c.size(), &a[0], a.size()));
|
BOOST_CHECK(zero_suppression_encode<uint8_t>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(b, c);
|
EQUAL_VECTORS(b, c);
|
||||||
zero_suppression_decode(&d[0], d.size(), b);
|
zero_suppression_decode<uint8_t>(&d[0], d.size(), b);
|
||||||
EQUAL_VECTORS(a, d);
|
EQUAL_VECTORS(a, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_zero_8 )
|
BOOST_AUTO_TEST_CASE( codec_zero_8 )
|
||||||
{
|
{
|
||||||
std::vector<char> a(257, 0), b, c, d(257, 0);
|
std::vector<uint8_t> a(257, 0), b, c, d(257, 0);
|
||||||
c += 0, 0, 0, 1;
|
c += 0, 0, 0, 1;
|
||||||
BOOST_CHECK(zero_suppression_encode(b, c.size(), &a[0], a.size()));
|
BOOST_CHECK(zero_suppression_encode<uint8_t>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(b, c);
|
EQUAL_VECTORS(b, c);
|
||||||
zero_suppression_decode(&d[0], d.size(), b);
|
zero_suppression_decode<uint8_t>(&d[0], d.size(), b);
|
||||||
EQUAL_VECTORS(a, d);
|
EQUAL_VECTORS(a, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE( codec_zero_9 )
|
BOOST_AUTO_TEST_CASE( codec_zero_9 )
|
||||||
{
|
{
|
||||||
std::vector<char> a(1000, 0), b, c, d(1000, 0);
|
std::vector<uint8_t> a(1000, 0), b, c, d(1000, 0);
|
||||||
c += 0, 0, 0, 0, 0, 0, 0, 232;
|
c += 0, 0, 0, 0, 0, 0, 0, 232;
|
||||||
BOOST_CHECK(zero_suppression_encode(b, c.size(), &a[0], a.size()));
|
BOOST_CHECK(zero_suppression_encode<uint8_t>(b, &a[0], a.size()));
|
||||||
EQUAL_VECTORS(b, c);
|
EQUAL_VECTORS(b, c);
|
||||||
zero_suppression_decode(&d[0], d.size(), b);
|
zero_suppression_decode<uint8_t>(&d[0], d.size(), b);
|
||||||
|
EQUAL_VECTORS(a, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_10 )
|
||||||
|
{
|
||||||
|
std::vector<uint16_t> a(1000, 0), b, c, d(1000, 0);
|
||||||
|
c += 0, 1000;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<uint16_t>(b, &a[0], a.size()));
|
||||||
|
EQUAL_VECTORS(b, c);
|
||||||
|
zero_suppression_decode<uint16_t>(&d[0], d.size(), b);
|
||||||
|
EQUAL_VECTORS(a, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( codec_zero_11 )
|
||||||
|
{
|
||||||
|
std::vector<uint16_t> a(65536, 0), b, c, d(65536, 0);
|
||||||
|
c += 0, 0;
|
||||||
|
BOOST_CHECK(zero_suppression_encode<uint16_t>(b, &a[0], a.size()));
|
||||||
|
EQUAL_VECTORS(b, c);
|
||||||
|
zero_suppression_decode<uint16_t>(&d[0], d.size(), b);
|
||||||
EQUAL_VECTORS(a, d);
|
EQUAL_VECTORS(a, d);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user