aboutsummaryrefslogtreecommitdiffstats
path: root/meowpp/math/utility.h
diff options
context:
space:
mode:
Diffstat (limited to 'meowpp/math/utility.h')
-rw-r--r--meowpp/math/utility.h197
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__