23 #ifndef GUL14_STATISTICS_H_
24 #define GUL14_STATISTICS_H_
30 #include <type_traits>
58 template <
typename ElementT>
61 return [](ElementT
const& el) -> ElementT
const&
76 template <typename DataT, typename = void, typename = std::enable_if_t<std::is_arithmetic<DataT>::value>>
78 DataT
min{ std::numeric_limits<DataT>::max() };
79 DataT
max{ std::numeric_limits<DataT>::lowest() };
82 template <
typename DataT>
83 struct MinMax<DataT, std::enable_if_t<std::is_floating_point<DataT>::value>> {
104 template <typename DataT, typename = std::enable_if_t<std::is_floating_point<DataT>::value>>
122 operator DataT() const noexcept {
126 auto sigma() const noexcept -> DataT {
130 auto mean() const noexcept -> DataT {
162 typename ElementT =
typename ContainerT::value_type,
163 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
164 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
165 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
167 auto mean(ContainerT
const& container, Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
170 container.cbegin(), container.cend(),
172 [accessor] (ResultT
const& accu, ElementT
const& el) {
173 return accu + static_cast<ResultT>(accessor(el)); } );
174 return sum /
static_cast<ResultT
>(container.size());
200 typename ElementT =
typename ContainerT::value_type,
201 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
202 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
203 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
205 auto rms(ContainerT
const& container, Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
208 container.cbegin(), container.cend(),
210 [accessor] (ResultT
const& accu, ElementT
const& el) {
211 return accu + std::pow(static_cast<ResultT>(accessor(el)), 2); } );
212 return std::sqrt(sum /
static_cast<ResultT
>(container.size()));
241 typename ElementT =
typename ContainerT::value_type,
242 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
243 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
244 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
246 auto median(ContainerT
const& container, Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
248 auto const len = container.size();
250 return std::numeric_limits<ResultT>::quiet_NaN();
254 auto data_copy = std::vector<DataT>{ };
255 data_copy.resize(len);
256 auto data_copy_it = data_copy.begin();
257 auto data_it = container.cbegin();
258 auto const data_end = container.cend();
259 for (; data_it != data_end; ++data_it) {
260 *(data_copy_it++) = accessor(*data_it);
264 auto middle = data_copy.begin() + (len / 2);
265 std::nth_element(data_copy.begin(), middle, data_copy.end());
266 auto median =
static_cast<ResultT
>(*middle);
271 std::nth_element(data_copy.begin(), middle - 1, data_copy.end());
272 median = (
median / 2) + (
static_cast<ResultT
>(*(middle - 1)) / 2);
308 template <
typename ContainerT,
309 typename ElementT =
typename ContainerT::value_type,
310 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
311 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
312 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
314 auto maximum(ContainerT
const& container, Accessor accessor = ElementAccessor<ElementT>()) -> DataT
316 constexpr
auto initial_value = std::numeric_limits<DataT>::has_quiet_NaN ?
317 std::numeric_limits<DataT>::quiet_NaN() : std::numeric_limits<DataT>::lowest();
320 container.cbegin(), container.cend(), initial_value,
321 [&accessor](DataT
const& accu, ElementT
const& el) -> DataT {
322 auto const val = accessor(el);
326 if (not (val <= accu))
362 template <
typename ContainerT,
363 typename ElementT =
typename ContainerT::value_type,
364 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
365 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
366 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
368 auto minimum(ContainerT
const& container, Accessor accessor = ElementAccessor<ElementT>()) -> DataT
370 constexpr
auto initial_value = std::numeric_limits<DataT>::has_quiet_NaN ?
371 std::numeric_limits<DataT>::quiet_NaN() : std::numeric_limits<DataT>::max();
374 container.cbegin(), container.cend(), initial_value,
375 [&accessor](DataT
const& accu, ElementT
const& el) -> DataT {
376 auto const val = accessor(el);
380 if (not (val >= accu))
421 template <
typename ContainerT,
422 typename ElementT =
typename ContainerT::value_type,
423 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
424 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
425 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
431 container.cbegin(), container.cend(),
433 [accessor] (MinMaxT
const& accu, ElementT
const& el) -> MinMaxT {
435 auto const val = accessor(el);
440 if (not (val >= out.min))
442 if (not (val <= out.max))
469 template <
typename ContainerT,
470 typename ElementT =
typename ContainerT::value_type,
471 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
472 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
473 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
476 Accessor accessor = ElementAccessor<ElementT>()) -> ContainerT&
478 while (outliers-- > 0 and cont.size() > 0) {
479 auto max_distant = std::max_element(cont.begin(), cont.end(),
480 [
mean =
mean(cont, accessor), accessor] (ElementT
const& a, ElementT
const& b)
482 cont.erase(max_distant);
493 template <
typename ContainerT,
494 typename ElementT =
typename ContainerT::value_type,
495 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
496 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
497 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
500 Accessor accessor = ElementAccessor<ElementT>()) -> std::vector<ElementT>
502 auto c = std::vector<ElementT>(cont.size());
503 std::copy(cont.cbegin(), cont.cend(), c.begin());
547 typename ElementT =
typename ContainerT::value_type,
548 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
549 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
550 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
554 auto const len = container.size();
559 auto mean_val = mean<ResultT>(container, accessor);
562 return { std::numeric_limits<ResultT>::quiet_NaN(), mean_val };
566 [mean_val, accessor] (ResultT
const& accu, ElementT
const& el)
567 { return accu + std::pow(static_cast<ResultT>(accessor(el)) - mean_val, 2); });
569 sum /=
static_cast<ResultT
>(container.size() - 1);
571 return { std::sqrt(sum), mean_val };
600 typename ElementT =
typename ContainerT::value_type,
601 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
602 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
604 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
606 auto accumulate(ContainerT
const& container, OpClosure op, Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
609 container.cbegin(), container.cend(),
611 [accessor, op] (ResultT
const& accu, ElementT
const& el) {
612 return op(accu, accessor(el)); } );
620 template <
typename IteratorT>
621 struct ContainerView {
622 IteratorT
const& begin_;
623 IteratorT
const& end_;
624 using value_type = std::decay_t<decltype(*begin_)>;
626 ContainerView(IteratorT
const& i1, IteratorT
const& i2)
634 auto cbegin() const noexcept -> IteratorT const&
638 auto cend() const noexcept -> IteratorT const&
643 auto size() const noexcept -> std::
size_t
645 return std::distance(begin_, end_);
649 template<
typename IteratorT>
650 auto make_view(IteratorT
const& cbegin, IteratorT
const& cend) -> ContainerView<IteratorT>
const
652 return ContainerView<IteratorT>{ cbegin, cend };
668 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
669 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
670 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
671 auto mean(IteratorT
const& begin, IteratorT
const& end,
672 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
674 return mean<ResultT>(make_view(begin, end), accessor);
688 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
689 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
690 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
691 auto rms(IteratorT
const& begin, IteratorT
const& end,
692 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
694 return rms<ResultT>(make_view(begin, end), accessor);
708 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
709 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
710 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
711 auto median(IteratorT
const& begin, IteratorT
const& end,
712 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
714 return median<ResultT>(make_view(begin, end), accessor);
726 template <
typename IteratorT,
727 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
728 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
729 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
730 auto maximum(IteratorT
const& begin, IteratorT
const& end,
731 Accessor accessor = ElementAccessor<ElementT>()) -> DataT
733 return maximum(make_view(begin, end), accessor);
745 template <
typename IteratorT,
746 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
747 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
748 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
749 auto minimum(IteratorT
const& begin, IteratorT
const& end,
750 Accessor accessor = ElementAccessor<ElementT>()) -> DataT
752 return minimum(make_view(begin, end), accessor);
764 template <
typename IteratorT,
765 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
766 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
767 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
768 auto min_max(IteratorT
const& begin, IteratorT
const& end,
769 Accessor accessor = ElementAccessor<ElementT>()) ->
MinMax<DataT>
771 return min_max(make_view(begin, end), accessor);
785 template <
typename IteratorT,
786 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
787 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
788 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
790 std::size_t outliers, Accessor accessor = ElementAccessor<ElementT>()) -> std::vector<ElementT>
807 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
808 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
809 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
813 return standard_deviation<ResultT>(make_view(begin, end), accessor);
829 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
830 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
831 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>,
833 auto accumulate(IteratorT
const& begin, IteratorT
const& end, OpClosure op,
834 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
836 return accumulate<ResultT>(make_view(begin, end), op, accessor);
A struct holding a standard deviation and a mean value.
Definition: statistics.h:105
constexpr auto abs(ValueT n) noexcept -> std::enable_if_t< std::is_unsigned< ValueT >::value, ValueT >
Compute the absolute value of a number.
Definition: num_util.h:53
DataT max
Maximum value.
Definition: statistics.h:79
auto mean(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
Calculate the arithmetic mean value of all elements in a container.
Definition: statistics.h:167
auto mean(IteratorT const &begin, IteratorT const &end, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: statistics.h:671
DataT mean_
The mean value.
Definition: statistics.h:108
double statistics_result_type
Type used to return statistic properties.
Definition: statistics.h:44
auto sigma() const noexcept -> DataT
Get the standard deviation value.
Definition: statistics.h:126
auto median(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
Find the median of all elements in a container.
Definition: statistics.h:246
DataT min
Minimum value.
Definition: statistics.h:78
auto remove_outliers(IteratorT const &begin, IteratorT const &end, std::size_t outliers, Accessor accessor=ElementAccessor< ElementT >()) -> std::vector< ElementT >
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: statistics.h:789
auto ElementAccessor()
Return a mock element accessor for containers.
Definition: statistics.h:59
auto maximum(IteratorT const &begin, IteratorT const &end, Accessor accessor=ElementAccessor< ElementT >()) -> DataT
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: statistics.h:730
auto min_max(IteratorT const &begin, IteratorT const &end, Accessor accessor=ElementAccessor< ElementT >()) -> MinMax< DataT >
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: statistics.h:768
DataT sigma_
The standard deviation (sigma) value.
Definition: statistics.h:107
auto standard_deviation(IteratorT const &begin, IteratorT const &end, Accessor accessor=ElementAccessor< ElementT >()) -> StandardDeviationMean< ResultT >
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: statistics.h:810
auto maximum(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> DataT
Return the maximum element value in a container.
Definition: statistics.h:314
auto mean() const noexcept -> DataT
Get the arithmetic mean value.
Definition: statistics.h:130
auto rms(IteratorT const &begin, IteratorT const &end, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: statistics.h:691
auto minimum(IteratorT const &begin, IteratorT const &end, Accessor accessor=ElementAccessor< ElementT >()) -> DataT
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: statistics.h:749
auto rms(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
Calculate the root mean square of all elements in a container.
Definition: statistics.h:205
auto accumulate(IteratorT const &begin, IteratorT const &end, OpClosure op, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: statistics.h:833
auto median(IteratorT const &begin, IteratorT const &end, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: statistics.h:711
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26
Object that is designed to holds two values: minimum and maximum of something.
Definition: statistics.h:77
Some metaprogramming traits for the General Utility Library.