/* * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Affero General Public License as published by the * Free Software Foundation; either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #ifndef _MATH_UTIL_H #define _MATH_UTIL_H #include #include #include #include // based on https://stackoverflow.com/questions/7616511/calculate-mean-and-standard-deviation-from-a-vector-of-samples-in-c-using-boos/12405793#comment32490316_12405793 template ()))>::type> inline T standard_deviation(Container&& c) { auto b = std::begin(c), e = std::end(c); auto size = std::distance(b, e); auto sum = std::accumulate(b, e, T()); auto mean = sum / size; if (size == 1) { return (T) 0; } T accum = T(); for (const auto d : c) { accum += (d - mean) * (d - mean); } return std::sqrt(accum / (size - 1)); } template ()))>::type> inline T mean(Container&& c) { auto b = std::begin(c), e = std::end(c); auto size = std::distance(b, e); auto sum = std::accumulate(b, e, T()); return sum / size; } // based off https://www.geeksforgeeks.org/finding-median-of-unsorted-array-in-linear-time-using-c-stl/ template inline T median(std::vector a) { std::size_t n = a.size(); // If size of the arr[] is even if (n % 2 == 0) { // Applying nth_element // on n/2th index std::nth_element(a.begin(), a.begin() + n / 2, a.end()); // Applying nth_element // on (n-1)/2 th index std::nth_element(a.begin(), a.begin() + (n - 1) / 2, a.end()); // Find the average of value at // index N/2 and (N-1)/2 return (T)(a[(n - 1) / 2] + a[n / 2]) / 2.0; } // If size of the arr[] is odd else { // Applying nth_element // on n/2 std::nth_element(a.begin(), a.begin() + n / 2, a.end()); // Value at index (N/2)th // is the median return (T)a[n / 2]; } } #endif