23#ifndef GUL17_STATISTICS_H_
24#define GUL17_STATISTICS_H_
58template <
typename ElementT>
78 DataT min{ std::numeric_limits<DataT>::max() };
79 DataT max{ std::numeric_limits<DataT>::lowest() };
82template <
typename DataT>
83struct MinMax<
DataT, std::
enable_if_t<std::is_floating_point<DataT>::value>> {
162 typename ElementT =
typename ContainerT::value_type,
165 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
169 auto const sum = std::accumulate(
173 return accu + static_cast<ResultT>(accessor(el)); } );
200 typename ElementT =
typename ContainerT::value_type,
203 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
207 auto const sum = std::accumulate(
211 return accu + std::pow(static_cast<ResultT>(accessor(el)), 2); } );
241 typename ElementT =
typename ContainerT::value_type,
244 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
250 return std::numeric_limits<ResultT>::quiet_NaN();
309 typename ElementT =
typename ContainerT::value_type,
312 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
316 constexpr auto initial_value = std::numeric_limits<DataT>::has_quiet_NaN ?
317 std::numeric_limits<DataT>::quiet_NaN() : std::numeric_limits<DataT>::lowest();
319 return std::accumulate(
322 auto const val = accessor(el);
326 if (not (val <= accu))
362template <
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>
368auto 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();
373 return std::accumulate(
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))
421template <
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>
430 auto const sum = std::accumulate(
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))
469template <
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)
481 {
return std::abs(accessor(a) -
mean) < std::abs(accessor(b) -
mean); });
482 cont.erase(max_distant);
493template <
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());
545template <
typename ResultT = statistics_result_type,
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 };
564 auto sum = std::accumulate(container.cbegin(), container.cend(),
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 };
598template <
typename ResultT = statistics_result_type,
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>
606auto accumulate(ContainerT
const& container, OpClosure op, Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
608 auto const sum = std::accumulate(
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)>>>
671auto mean(IteratorT
const& begin, IteratorT
const& end,
672 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
674 return mean<ResultT>(make_view(begin, end), accessor);
686template <
typename ResultT = statistics_result_type,
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)>>>
691auto rms(IteratorT
const& begin, IteratorT
const& end,
692 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
694 return rms<ResultT>(make_view(begin, end), accessor);
706template <
typename ResultT = statistics_result_type,
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)>>>
711auto median(IteratorT
const& begin, IteratorT
const& end,
712 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
714 return median<ResultT>(make_view(begin, end), accessor);
726template <
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);
745template <
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);
764template <
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)>>>
768auto min_max(IteratorT
const& begin, IteratorT
const& end,
769 Accessor accessor = ElementAccessor<ElementT>()) ->
MinMax<DataT>
771 return min_max(make_view(begin, end), accessor);
785template <
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>
805template <
typename ResultT = statistics_result_type,
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);
827template <
typename ResultT = statistics_result_type,
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)>>,
833auto 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
auto constexpr bit_set(unsigned bit) noexcept -> ReturnT
Set a bit in an integral type.
Definition bit_manip.h:121
auto min_max(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> MinMax< DataT >
Find the minimum and maximum element values in a container.
Definition statistics.h:427
auto minimum(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> DataT
Return the minimum element value in a container.
Definition statistics.h:368
DataT sigma_
The standard deviation (sigma) value.
Definition statistics.h:107
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
double statistics_result_type
Type used to return statistic properties.
Definition statistics.h:44
DataT max
Maximum value.
Definition statistics.h:79
auto median(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
Find the median of all elements in a container.
Definition statistics.h:246
auto remove_outliers(ContainerT &&cont, std::size_t outliers, Accessor accessor=ElementAccessor< ElementT >()) -> ContainerT &
Remove elements that are far away from other elements.
Definition statistics.h:475
auto accumulate(ContainerT const &container, OpClosure op, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
Calculate some aggregate value from all elements of a container.
Definition statistics.h:606
auto standard_deviation(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> StandardDeviationMean< ResultT >
Calculate the standard deviation of all elements in a container.
Definition statistics.h:552
auto sigma() const noexcept -> DataT
Get the standard deviation value.
Definition statistics.h:126
DataT mean_
The mean value.
Definition statistics.h:108
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 ElementAccessor()
Return a mock element accessor for containers.
Definition statistics.h:59
auto mean() const noexcept -> DataT
Get the arithmetic mean value.
Definition statistics.h:130
auto maximum(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> DataT
Return the maximum element value in a container.
Definition statistics.h:314
DataT min
Minimum value.
Definition statistics.h:78
Definition of macros used internally by GUL.
Namespace gul17 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.