#pragma once #include "types.h" #include "gc.h" #include #include #include #include #undef max #undef min template class VT> size_t count(const VT& v) { return v.size; } template constexpr static size_t count(const T&) { return 1; } // TODO: Specializations for dt/str/none template class VT> types::GetLongType sum(const VT& v) { types::GetLongType ret = 0; for (auto _v : v) ret += _v; return ret; } template class VT> //types::GetFPType double avg(const VT& v) { return (sum(v) / static_cast(v.size)); } template class VT, class Ret> void sqrt(const VT& v, Ret& ret) { for (uint32_t i = 0; i < v.size; ++i) ret[i] = sqrt(v[i]); } template class VT> VT sqrt(const VT& v) { VT ret(v.size); sqrt(v, ret); return ret; } template T truncate(const T& v, const uint32_t precision) { auto multiplier = pow(10, precision); if (v >= std::numeric_limits::max()/multiplier || aq_fp_precision <= precision) return v; else return round(v * multiplier)/multiplier; } template class VT> VT truncate(const VT& v, const uint32_t precision) { if (aq_fp_precision <= precision) return v.subvec_memcpy(); auto multiplier = pow(10, precision); auto max_truncate = std::numeric_limits::max()/multiplier; VT ret(v.size); for (uint32_t i = 0; i < v.size; ++i) { // round or trunc?? ret[i] = v[i] < max_truncate ? round(v[i] * multiplier)/multiplier : v[i]; } return ret; } template class VT> T max(const VT& v) { T max_v = std::numeric_limits::min(); for (const auto& _v : v) max_v = max_v > _v ? max_v : _v; return max_v; } template class VT> T min(const VT& v) { T min_v = std::numeric_limits::max(); for (const auto& _v : v) min_v = min_v < _v ? min_v : _v; return min_v; } // simplify this using a template std::binary_function = std::less; template class VT, class Ret> void mins(const VT& arr, Ret& ret) { const uint32_t& len = arr.size; T min = std::numeric_limits::max(); for (int i = 0; i < len; ++i) { if (arr[i] < min) min = arr[i]; ret[i] = min; } } template class VT> decayed_t mins(const VT& arr) { decayed_t ret(arr.size); mins(arr, ret); return ret; } template class VT, class Ret> void maxs(const VT& arr, Ret& ret) { const uint32_t& len = arr.size; T max = std::numeric_limits::min(); for (int i = 0; i < len; ++i) { if (arr[i] > max) max = arr[i]; ret[i] = max; } } template class VT> decayed_t maxs(const VT& arr) { decayed_t ret(arr.size); maxs(arr, ret); return ret; } template class VT, class Ret> void minw(uint32_t w, const VT& arr, Ret& ret) { const uint32_t& len = arr.size; std::deque> cache; for (int i = 0; i < len; ++i) { if (!cache.empty() && cache.front().second == i - w) cache.pop_front(); while (!cache.empty() && cache.back().first > arr[i]) cache.pop_back(); cache.push_back({ arr[i], i }); ret[i] = cache.front().first; } } template class VT> decayed_t minw(uint32_t w, const VT& arr) { decayed_t ret(arr.size); minw(w, arr, ret); return ret; } template class VT, class Ret> void maxw(uint32_t w, const VT& arr, Ret& ret) { const uint32_t& len = arr.size; std::deque> cache; for (int i = 0; i < len; ++i) { if (!cache.empty() && cache.front().second == i - w) cache.pop_front(); while (!cache.empty() && cache.back().first < arr[i]) cache.pop_back(); cache.push_back({ arr[i], i }); ret[i] = cache.front().first; } } template class VT> inline decayed_t maxw(uint32_t w, const VT& arr) { decayed_t ret(arr.size); maxw(w, arr, ret); return ret; } template class VT, class Ret> void ratiow(uint32_t w, const VT& arr, Ret& ret) { typedef std::decay_t> FPType; uint32_t len = arr.size; if (arr.size <= w) len = 1; w = w > len ? len : w; ret[0] = 0; for (uint32_t i = 0; i < w; ++i) ret[i] = arr[i] / (FPType)arr[0]; for (uint32_t i = w; i < arr.size; ++i) ret[i] = arr[i] / (FPType) arr[i - w]; } template class VT> inline decayed_t> ratiow(uint32_t w, const VT& arr) { typedef std::decay_t> FPType; decayed_t ret(arr.size); ratiow(w, arr, ret); return ret; } template class VT> inline decayed_t> ratios(const VT& arr) { return ratiow(1, arr); } template class VT, class Ret> inline void ratios(const VT& arr, Ret& ret) { return ratiow(1, arr, ret); } template class VT, class Ret> void sums(const VT& arr, Ret& ret) { const uint32_t& len = arr.size; uint32_t i = 0; if (len) ret[i++] = arr[0]; for (; i < len; ++i) ret[i] = ret[i - 1] + arr[i]; } template class VT> inline decayed_t> sums(const VT& arr) { decayed_t> ret(arr.size); sums(arr, ret); return ret; } template class VT, class Ret> void avgs(const VT& arr, Ret& ret) { const uint32_t& len = arr.size; typedef types::GetFPType> FPType; uint32_t i = 0; types::GetLongType s; if (len) s = ret[i++] = arr[0]; for (; i < len; ++i) ret[i] = (s += arr[i]) / (FPType)(i + 1); } template class VT> inline decayed_t>> avgs(const VT& arr) { typedef types::GetFPType> FPType; decayed_t ret(arr.size); avgs(arr, ret); return ret; } template class VT, class Ret> void sumw(uint32_t w, const VT& arr, Ret& ret) { const uint32_t& len = arr.size; uint32_t i = 0; w = w > len ? len : w; if (len) ret[i++] = arr[0]; for (; i < w; ++i) ret[i] = ret[i - 1] + arr[i]; for (; i < len; ++i) ret[i] = ret[i - 1] + arr[i] - arr[i - w]; } template class VT> decayed_t> sumw(uint32_t w, const VT& arr) { decayed_t> ret(arr.size); sumw(w, arr, ret); return ret; } template class VT, class Ret> void avgw(uint32_t w, const VT& arr, Ret& ret) { typedef types::GetFPType> FPType; const uint32_t& len = arr.size; uint32_t i = 0; types::GetLongType s{}; w = w > len ? len : w; if (len) s = ret[i++] = arr[0]; for (; i < w; ++i) ret[i] = (s += arr[i]) / (FPType)(i + 1); for (; i < len; ++i) ret[i] = ret[i - 1] + (arr[i] - arr[i - w]) / (FPType)w; } template class VT> inline decayed_t>> avgw(uint32_t w, const VT& arr) { typedef types::GetFPType> FPType; const uint32_t& len = arr.size; decayed_t ret(len); avgw(w, arr, ret); return ret; } template class VT, class Ret, bool sd = false> void varw(uint32_t w, const VT& arr, Ret& ret) { using FPType = types::GetFPType>; const uint32_t& len = arr.size; uint32_t i = 0; types::GetLongType s{}; w = w > len ? len : w; FPType EnX {}, MnX{}; if (len) { s = arr[0]; MnX = 0; EnX = arr[0]; ret[i++] = 0; } for (; i < len; ++i){ s += arr[i]; FPType _EnX = s / (FPType)(i + 1); MnX += (arr[i] - EnX) * (arr[i] - _EnX); EnX = _EnX; ret[i] = MnX / (FPType)(i + 1); if constexpr(sd) ret[i-1] = sqrt(ret[i-1]); } const float rw = 1.f / (float)w; s *= rw; for (; i < len; ++i){ const auto dw = arr[i] - arr[i - w - 1]; const auto sw = arr[i] + arr[i - w - 1]; const auto dex = dw * rw; ret[i] = ret[i-1] - dex*(s + s + dex - sw); if constexpr(sd) ret[i-1] = sqrt(ret[i-1]); s += dex; } if constexpr(sd) if(i) ret[i-1] = sqrt(ret[i-1]); } template class VT, bool sd = false> inline decayed_t>> varw(uint32_t w, const VT& arr) { using FPType = types::GetFPType>; decayed_t ret(arr.size); varw>>, sd>(w, arr, ret); return ret; } template class VT> types::GetFPType>> var(const VT& arr) { typedef types::GetFPType>> FPType; const uint32_t& len = arr.size; uint32_t i = 0; types::GetLongType s{0}; types::GetLongType ssq{0}; if (len) { s = arr[0]; ssq = arr[0] * arr[0]; } for (; i < len; ++i){ s += arr[i]; ssq += arr[i] * arr[i]; } return (ssq - s * s / (FPType)(len + 1)) / (FPType)(len + 1); } template class VT, class Ret, bool sd = false> void vars(const VT& arr, Ret& ret) { typedef types::GetFPType> FPType; const uint32_t& len = arr.size; uint32_t i = 0; types::GetLongType s{}; FPType MnX{}; FPType EnX {}; if (len) { s = arr[0]; MnX = 0; EnX = arr[0]; ret[i++] = 0; } for (; i < len; ++i){ s += arr[i]; FPType _EnX = s / (FPType)(i + 1); MnX += (arr[i] - EnX) * (arr[i] - _EnX); printf("%d %ld ", arr[i], MnX); EnX = _EnX; ret[i] = MnX / (FPType)(i + 1); if constexpr(sd) ret[i] = sqrt(ret[i]); } } template class VT, bool sd = false> inline decayed_t>> vars(const VT& arr) { typedef types::GetFPType> FPType; decayed_t ret(arr.size); vars>>, sd>(arr, ret); return ret; } template class VT, class T2, template class VT2 > auto corr(const VT& x, const VT2&y) { typedef types::Coercion, decays> InnerType; typedef types::GetLongType LongType; typedef types::GetFPType FPType; // assert(x.size == y.size); const uint32_t& len = x.size; LongType sx{0}, sy{0}, sxy{0}, sx2{0}, sy2{0}; for (uint32_t i = 0; i < len; ++i){ sx += x[i]; sx2 += x[i] * x[i]; sy += y[i]; sxy += x[i] * y[i]; sy2 += y[i] * y[i]; } return (len*sxy - FPType(sx*sy)) / (sqrt( (len*sx2 - FPType(sx*sx)) * (len*sy2 - FPType(sy*sy)) ) ); } void pow(auto x, auto y, auto& z) { z = pow(x, y); } template class VT> inline types::GetFPType>> stddev(const VT& arr) { return sqrt(var(arr)); } template class VT> inline decayed_t>> stddevs(const VT& arr) { return vars(arr); } template class VT> inline decayed_t>> stddevw(uint32_t w, const VT& arr) { return varw(w, arr); } template class VT, class Ret> inline auto stddevs(const VT& arr, Ret& ret) { return vars(arr, ret); } template class VT, class Ret> inline auto stddevw(uint32_t w, const VT& arr, Ret& ret) { return varw(w, arr, ret); } // use getSignedType template class VT, class Ret> void deltas(const VT& arr, Ret& ret) { const uint32_t& len = arr.size; uint32_t i = 0; if (len) ret[i++] = 0; for (; i < len; ++i) ret[i] = arr[i] - arr[i - 1]; } template class VT> inline decayed_t deltas(const VT& arr) { decayed_t ret(arr.size); deltas(arr, ret); return ret; } template class VT, class Ret> void prev(const VT& arr, Ret& ret) { const uint32_t& len = arr.size; uint32_t i = 0; if (len) ret[i++] = arr[0]; for (; i < len; ++i) ret[i] = arr[i - 1]; } template class VT> inline decayed_t prev(const VT& arr) { decayed_t ret(arr.size); prev(arr, ret); return ret; } template class VT, class Ret> void aggnext(const VT& arr, Ret& ret) { const uint32_t& len = arr.size; uint32_t i = 1; for (; i < len; ++i) ret[i - 1] = arr[i]; if (len > 0) ret[len - 1] = arr[len - 1]; } template class VT> inline decayed_t aggnext(const VT& arr) { decayed_t ret(arr.size); aggnext(arr, ret); return ret; } template class VT> T last(const VT& arr) { if (!arr.size) return 0; return arr[arr.size - 1]; } template class VT> T first(const VT& arr) { if (!arr.size) return 0; return arr[0]; } #define __DEFAULT_AGGREGATE_FUNCTION__(NAME, RET) \ template constexpr T NAME(const T& v) { return RET; } // non-aggreation count. E.g. SELECT COUNT(col) from table; template constexpr T count(const T&) { return 1; } template constexpr T var(const T&) { return 0; } template constexpr T vars(const T&) { return 0; } template constexpr T varw(uint32_t, const T&) { return 0; } template constexpr T stddev(const T&) { return 0; } template constexpr T stddevs(const T&) { return 0; } template constexpr T stddevw(uint32_t, const T&) { return 0; } template constexpr T max(const T& v) { return v; } template constexpr T min(const T& v) { return v; } template constexpr T avg(const T& v) { return v; } template constexpr T sum(const T& v) { return v; } template constexpr T maxw(uint32_t, const T& v) { return v; } template constexpr T minw(uint32_t, const T& v) { return v; } template constexpr T avgw(uint32_t, const T& v) { return v; } template constexpr T sumw(uint32_t, const T& v) { return v; } template constexpr T ratiow(uint32_t, const T&) { return 1; } template constexpr T maxs(const T& v) { return v; } template constexpr T mins(const T& v) { return v; } template constexpr T avgs(const T& v) { return v; } template constexpr T sums(const T& v) { return v; } template constexpr T last(const T& v) { return v; } template constexpr T prev(const T& v) { return v; } template constexpr T aggnext(const T& v) { return v; } template constexpr T daltas(const T&) { return 0; } template constexpr T ratios(const T&) { return 1; }