24 #ifndef GUL14_STATISTICS_H_
25 #define GUL14_STATISTICS_H_
31 #include <type_traits>
52 template <
typename ElementT>
55 return [](ElementT
const& el) -> ElementT
const&
70 template <typename DataT, typename = void, typename = std::enable_if_t<std::is_arithmetic<DataT>::value>>
72 DataT
min{ std::numeric_limits<DataT>::max() };
73 DataT
max{ std::numeric_limits<DataT>::lowest() };
76 template <
typename DataT>
77 struct MinMax<DataT, std::enable_if_t<std::is_floating_point<DataT>::value>> {
98 template <typename DataT, typename = std::enable_if_t<std::is_floating_point<DataT>::value>>
116 operator DataT() const noexcept {
120 auto sigma() const noexcept -> DataT {
124 auto mean() const noexcept -> DataT {
156 typename ElementT =
typename ContainerT::value_type,
157 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
158 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
159 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
161 auto mean(ContainerT
const& container, Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
164 container.cbegin(), container.cend(),
166 [accessor] (ResultT
const& accu, ElementT
const& el) {
167 return accu + static_cast<ResultT>(accessor(el)); } );
168 return sum /
static_cast<ResultT
>(container.size());
194 typename ElementT =
typename ContainerT::value_type,
195 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
196 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
197 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
199 auto rms(ContainerT
const& container, Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
202 container.cbegin(), container.cend(),
204 [accessor] (ResultT
const& accu, ElementT
const& el) {
205 return accu + std::pow(static_cast<ResultT>(accessor(el)), 2); } );
206 return std::sqrt(sum /
static_cast<ResultT
>(container.size()));
235 typename ElementT =
typename ContainerT::value_type,
236 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
237 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
238 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
240 auto median(ContainerT
const& container, Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
242 auto const len = container.size();
244 return std::numeric_limits<ResultT>::quiet_NaN();
248 auto data_copy = std::vector<DataT>{ };
249 data_copy.resize(len);
250 auto data_copy_it = data_copy.begin();
251 auto data_it = container.cbegin();
252 auto const data_end = container.cend();
253 for (; data_it != data_end; ++data_it) {
254 *(data_copy_it++) = accessor(*data_it);
258 auto middle = data_copy.begin() + (len / 2);
259 std::nth_element(data_copy.begin(), middle, data_copy.end());
260 auto median =
static_cast<ResultT
>(*middle);
265 std::nth_element(data_copy.begin(), middle - 1, data_copy.end());
266 median = (
median / 2) + (
static_cast<ResultT
>(*(middle - 1)) / 2);
302 template <
typename ContainerT,
303 typename ElementT =
typename ContainerT::value_type,
304 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
305 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
306 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
308 auto maximum(ContainerT
const& container, Accessor accessor = ElementAccessor<ElementT>()) -> DataT
310 constexpr
auto initial_value = std::numeric_limits<DataT>::has_quiet_NaN ?
311 std::numeric_limits<DataT>::quiet_NaN() : std::numeric_limits<DataT>::lowest();
314 container.cbegin(), container.cend(), initial_value,
315 [&accessor](DataT
const& accu, ElementT
const& el) -> DataT {
316 auto const val = accessor(el);
320 if (not (val <= accu))
356 template <
typename ContainerT,
357 typename ElementT =
typename ContainerT::value_type,
358 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
359 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
360 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
362 auto minimum(ContainerT
const& container, Accessor accessor = ElementAccessor<ElementT>()) -> DataT
364 constexpr
auto initial_value = std::numeric_limits<DataT>::has_quiet_NaN ?
365 std::numeric_limits<DataT>::quiet_NaN() : std::numeric_limits<DataT>::max();
368 container.cbegin(), container.cend(), initial_value,
369 [&accessor](DataT
const& accu, ElementT
const& el) -> DataT {
370 auto const val = accessor(el);
374 if (not (val >= accu))
415 template <
typename ContainerT,
416 typename ElementT =
typename ContainerT::value_type,
417 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
418 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
419 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
425 container.cbegin(), container.cend(),
427 [accessor] (MinMaxT
const& accu, ElementT
const& el) -> MinMaxT {
429 auto const val = accessor(el);
434 if (not (val >= out.min))
436 if (not (val <= out.max))
463 template <
typename ContainerT,
464 typename ElementT =
typename ContainerT::value_type,
465 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
466 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
467 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
470 Accessor accessor = ElementAccessor<ElementT>()) -> ContainerT&
472 while (outliers-- > 0 and cont.size() > 0) {
473 auto max_distant = std::max_element(cont.begin(), cont.end(),
474 [
mean =
mean(cont, accessor), accessor] (ElementT
const& a, ElementT
const& b)
476 cont.erase(max_distant);
487 template <
typename ContainerT,
488 typename ElementT =
typename ContainerT::value_type,
489 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
490 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
491 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
494 Accessor accessor = ElementAccessor<ElementT>()) -> std::vector<ElementT>
496 auto c = std::vector<ElementT>(cont.size());
497 std::copy(cont.cbegin(), cont.cend(), c.begin());
541 typename ElementT =
typename ContainerT::value_type,
542 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
543 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
544 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
548 auto const len = container.size();
553 auto mean_val = mean<ResultT>(container, accessor);
556 return { std::numeric_limits<ResultT>::quiet_NaN(), mean_val };
560 [mean_val, accessor] (ResultT
const& accu, ElementT
const& el)
561 { return accu + std::pow(static_cast<ResultT>(accessor(el)) - mean_val, 2); });
563 sum /=
static_cast<ResultT
>(container.size() - 1);
565 return { std::sqrt(sum), mean_val };
594 typename ElementT =
typename ContainerT::value_type,
595 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
596 typename DataT =
typename std::decay_t<std::result_of_t<Accessor(ElementT)>>,
598 typename = std::enable_if_t<IsContainerLike<ContainerT>::value>
600 auto accumulate(ContainerT
const& container, OpClosure op, Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
603 container.cbegin(), container.cend(),
605 [accessor, op] (ResultT
const& accu, ElementT
const& el) {
606 return op(accu, accessor(el)); } );
614 template <
typename IteratorT>
615 struct ContainerView {
616 IteratorT
const& begin_;
617 IteratorT
const& end_;
618 using value_type = std::decay_t<decltype(*begin_)>;
620 ContainerView(IteratorT
const& i1, IteratorT
const& i2)
628 auto cbegin() const noexcept -> IteratorT const&
632 auto cend() const noexcept -> IteratorT const&
637 auto size() const noexcept -> std::
size_t
639 return std::distance(begin_, end_);
643 template<
typename IteratorT>
644 auto make_view(IteratorT
const& cbegin, IteratorT
const& cend) -> ContainerView<IteratorT>
const
646 return ContainerView<IteratorT>{ cbegin, cend };
662 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
663 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
664 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
665 auto mean(IteratorT
const& begin, IteratorT
const& end,
666 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
668 return mean<ResultT>(make_view(begin, end), accessor);
682 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
683 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
684 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
685 auto rms(IteratorT
const& begin, IteratorT
const& end,
686 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
688 return rms<ResultT>(make_view(begin, end), accessor);
702 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
703 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
704 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
705 auto median(IteratorT
const& begin, IteratorT
const& end,
706 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
708 return median<ResultT>(make_view(begin, end), accessor);
720 template <
typename IteratorT,
721 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
722 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
723 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
724 auto maximum(IteratorT
const& begin, IteratorT
const& end,
725 Accessor accessor = ElementAccessor<ElementT>()) -> DataT
727 return maximum(make_view(begin, end), accessor);
739 template <
typename IteratorT,
740 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
741 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
742 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
743 auto minimum(IteratorT
const& begin, IteratorT
const& end,
744 Accessor accessor = ElementAccessor<ElementT>()) -> DataT
746 return minimum(make_view(begin, end), accessor);
758 template <
typename IteratorT,
759 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
760 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
761 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
762 auto min_max(IteratorT
const& begin, IteratorT
const& end,
763 Accessor accessor = ElementAccessor<ElementT>()) ->
MinMax<DataT>
765 return min_max(make_view(begin, end), accessor);
779 template <
typename IteratorT,
780 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
781 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
782 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
784 std::size_t outliers, Accessor accessor = ElementAccessor<ElementT>()) -> std::vector<ElementT>
801 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
802 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
803 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>>
807 return standard_deviation<ResultT>(make_view(begin, end), accessor);
823 typename ElementT = std::decay_t<decltype(*std::declval<IteratorT>())>,
824 typename Accessor = std::result_of_t<decltype(ElementAccessor<ElementT>())(ElementT)>(*)(ElementT
const&),
825 typename DataT = std::decay_t<std::result_of_t<Accessor(ElementT)>>,
827 auto accumulate(IteratorT
const& begin, IteratorT
const& end, OpClosure op,
828 Accessor accessor = ElementAccessor<ElementT>()) -> ResultT
830 return accumulate<ResultT>(make_view(begin, end), op, accessor);
A struct holding a standard deviation and a mean value.
Definition: statistics.h:99
DataT mean_
The mean value.
Definition: statistics.h:102
auto sigma() const noexcept -> DataT
Get the standard deviation value.
Definition: statistics.h:120
DataT sigma_
The standard deviation (sigma) value.
Definition: statistics.h:101
auto mean() const noexcept -> DataT
Get the arithmetic mean value.
Definition: statistics.h:124
Definition of macros used internally by GUL.
Namespace gul14 contains all functions and classes of the General Utility Library.
Definition: doxygen.h:26
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:47
auto mean(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
Calculate the arithmetic mean value of all elements in a container.
Definition: statistics.h:161
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:665
double statistics_result_type
Type used to return statistic properties.
Definition: statistics.h:38
auto median(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
Find the median of all elements in a container.
Definition: statistics.h:240
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:783
auto ElementAccessor()
Return a mock element accessor for containers.
Definition: statistics.h:53
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:724
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:762
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:804
auto maximum(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> DataT
Return the maximum element value in a container.
Definition: statistics.h:308
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:685
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:743
auto rms(ContainerT const &container, Accessor accessor=ElementAccessor< ElementT >()) -> ResultT
Calculate the root mean square of all elements in a container.
Definition: statistics.h:199
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:827
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:705
Object that is designed to holds two values: minimum and maximum of something.
Definition: statistics.h:71
DataT max
Maximum value.
Definition: statistics.h:73
DataT min
Minimum value.
Definition: statistics.h:72
Some metaprogramming traits for the General Utility Library.