diff options
Diffstat (limited to 'meowpp/math/utility.h')
-rw-r--r-- | meowpp/math/utility.h | 197 |
1 files changed, 127 insertions, 70 deletions
diff --git a/meowpp/math/utility.h b/meowpp/math/utility.h index 9bfbb7a..43b4785 100644 --- a/meowpp/math/utility.h +++ b/meowpp/math/utility.h @@ -2,81 +2,138 @@ #define math_utility_H__ #include <cstdlib> +#include <vector> +#include <algorithm> +#include <cmath> namespace meow{ - static const double PI = 3.14159265358979323846264338327950288; - //# - //# === meow:: *Functios* in math/utility.h - //# - //# [options="header",width="100%",cols="1>s,5<,1<,10<",grid="rows"] - //# |============================================================== - //# |Name | Parameters | Return_Type | Description - - //# |noEPS<T> |(T `value`, T `eps` = 1e-9) | T | - //# 如果abs(輸入的數值) < eps, 則回傳0, 否則回傳輸入的數值 - template<class T> - inline T noEPS(T value, T eps = 1e-9); - - - //# |normalize<T> |(T `lower`, T `upper`, \ T value) - //# | T | `(value - lower) / (upper - lower)` - template<class T> - inline T normalize(T lower, T upper, T value); - - - //# |denormalize<T> |(T `lower`, T `upper`, - //# \ T `ratio`) | T | `lower + (upper - lower) * ratio` - template<class T> - inline T denormalize(T lower, T upper, T ratio); - - - //# |ratioMapping<T>|(T `l1`, T `u1`, - //# \T `m1`, T `l2`,\T `u2`) - //# | T | `denormalize(l2, u2, normalize(l1, u1, m1))` - template<class T> - inline T ratioMapping(T l1, T u1, T m1, T l2, T u2); - - - //# |inRange<T> |(T const& `mn`, T const& `mx`, \ T const& `v`) | T | - //# `std::max(mn, std::min(mx, v))` - template<class T> - inline T inRange(T const& mn, T const& mx, T const& v); - - - //# |squ<T> |(T const& `x`) | T| `x * x` - template<class T> - inline T squ(T const& x); - - - //# |cub<T> |(T const& `x`) | T| `x * x * x` - template<class T> - inline T cub(T const& x); +//! 圓周率... +static const double PI = 3.14159265358979323846264338327950288; - //# |average<T>|(T const& `beg`, T const& `end`, \ double `sigs`)| T| - //# 只將 `sigs` 個標準差以內的數據拿來取平均 - template<class T> - inline double average(T const& beg, T const& end, double sigs); - - - //# |average<T>|(T const& `beg`, T const& `end`, - //# \ T const& `p`, double `sigs`)| T| 同上, 不過這次用 `p` 來加權平均 - template<class T> - inline double average(T const& beg, T const& end, T const& p, double sigs); - - //# |============================================================== - - - //# - //# [NOTE] - //# ==================================== - //# * 額外附贈一個 `const double PI = 3.141592653589......` - //# ==================================== - //# - //# ''' - //# +/*! + * @brief 如果abs(輸入的數值) < eps, 則回傳0, 否則回傳輸入的數值 + */ +template<class T> +inline T noEPS(T value, T eps = 1e-9){ + T epsp((eps < T(0)) ? -eps : eps); + return ((value < -epsp || value > epsp) ? value : T(0)); } -#include "utility.hpp" +/*! + * @brief \c (value-lower)/(upper-lower) + */ +template<class T> +inline T normalize(T lower, T upper, T value){ + return (value - lower) / (upper - lower); +} + +/*! + * @brief \c (lower+_ratio*(upper-lower)) + */ +template<class T> +inline T denormalize(T lower, T upper, T _ratio){ + return lower + _ratio * (upper - lower); +} + +/*! + * @brief \c denormalize(l2,u2,normalize(l1,u1,m1)) + */ +template<class T> +inline T ratioMapping(T l1, T u1, T m1, T l2, T u2){ + return denormalize(l2, u2, normalize(l1, u1, m1)); +} + +/*! + * @brief \c std::min(mx,std::max(mn,v)) + */ +template<class T> +inline T inRange(T const& mn, T const& mx, T const& v){ + return std::min(mx, std::max(mn, v)); +} + +/*! + * @brief \c x*x + */ +template<class T> +inline T squ(T const& x){ + return x * x; +} + +/*! + * @brief \c x*x*x + */ +template<class T> +inline T cub(T const& x){ + return x * x * x; +} + +/*! + * @brief 只將 \c sigs 個標準差以內的數據拿來取平均 + */ +template<class T> +inline double average(T const& beg, T const& end, double sigs){ + int N = 0; + double av = 0; + for(T it = beg; it != end; it++, N++){ + av += *it; + } + av /= N; + double sig = 0; + for(T it = beg; it != end; it++){ + sig += (*it - av) * (*it - av); + } + sig = sqrt(sig / N); + double lower = av - sig * sigs, upper = av + sig * sigs; + double ret = 0, retn = 0; + for(T it = beg; it != end; it++){ + if(lower <= *it && *it <= upper){ + ret += *it; + retn++; + } + } + return ret / retn; +} + +/*! + * @brief 只將 \c sigs 個標準差以內的數據拿來取平均, 不過這次用 \c p 來加權平均 + */ +template<class T> +inline double average(T const& beg, T const& end, T const& p, double sigs){ + int N = 0; + double ps = 0; + for(T it = beg, ip = p; it != end; it++, N++, ip++){ + ps += *ip; + } + double av = 0; + for(T it = beg, ip = p; it != end; it++, ip++){ + av += *it * *ip / ps; + } + double sig = 0; + for(T it = beg, ip = p; it != end; it++, ip++){ + sig += *ip / ps * (*it - av) * (*it - av); + } + sig = sqrt(sig); + double lower = av - sig * sigs, upper = av + sig * sigs; + double ret = 0, retn = 0; + for(T it = beg, ip = p; it != end; it++, ip++){ + if(lower <= *it && *it <= upper){ + ret += *it * *ip; + retn += *ip; + } + } + if(retn <= 1e-10) return av; + return ret / retn; +} + +/*! + * @brief 就只是個取絕對值 + */ +template<class T> +inline T tAbs(T const& t){ + return (t < 0 ? -t : t); +} + +} #endif // math_utility_H__ |