#pragma once #include #include #include #include #include #include namespace NYql { namespace NUdf { #define CONST_FUNCS(XX) \ XX(Pi, M_PI) \ XX(E, M_E) \ XX(Eps, std::numeric_limits::epsilon()) \ XX(RoundDownward, 0) \ XX(RoundToNearest, 1) \ XX(RoundTowardZero, 2) \ XX(RoundUpward, 3) #define SINGLE_ARG_FUNCS(XX) \ XX(Abs, Abs) \ XX(Acos, acos) \ XX(Asin, asin) \ XX(Asinh, asin) \ XX(Atan, atan) \ XX(Cbrt, cbrt) \ XX(Ceil, ceil) \ XX(Cos, cos) \ XX(Cosh, cosh) \ XX(Erf, Erf) \ XX(Exp, exp) \ XX(Exp2, Exp2) \ XX(Fabs, fabs) \ XX(Floor, std::floor) \ XX(Lgamma, LogGamma) \ XX(Rint, rint) \ XX(Sin, sin) \ XX(Sinh, sinh) \ XX(Sqrt, sqrt) \ XX(Tan, tan) \ XX(Tanh, tanh) \ XX(Tgamma, tgamma) \ XX(Trunc, trunc) \ XX(IsFinite, std::isfinite) \ XX(IsInf, std::isinf) \ XX(IsNaN, std::isnan) #define TWO_ARGS_FUNCS(XX) \ XX(Atan2, atan2, double) \ XX(Fmod, fmod, double) \ XX(Hypot, hypot, double) \ XX(Remainder, remainder, double) \ XX(Pow, pow, double) \ XX(Ldexp, ldexp, int) #define POSITIVE_SINGLE_ARG_FUNCS(XX) \ XX(Log, log) \ XX(Log2, Log2) \ XX(Log10, log10) #define CONST_IMPL(name, cnst) \ extern "C" UDF_ALWAYS_INLINE \ void name##IR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* /*args*/) {\ *result = TUnboxedValuePod(cnst); \ } #define SINGLE_ARG_IMPL(name, func) \ extern "C" UDF_ALWAYS_INLINE \ void name##IR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { \ *result = TUnboxedValuePod(func(args[0].Get())); \ } #define TWO_ARGS_IMPL(name, func, secondType) \ extern "C" UDF_ALWAYS_INLINE \ void name##IR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { \ *result = TUnboxedValuePod(func(args[0].Get(), args[1].Get())); \ } #define POSITIVE_SINGLE_ARG_IMPL(name, func) \ extern "C" UDF_ALWAYS_INLINE \ void name##IR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { \ double input = args[0].Get(); \ if (input > 0) { \ *result = TUnboxedValuePod(func(input)); \ } else { \ *result = TUnboxedValuePod(static_cast(NAN)); \ } \ } CONST_FUNCS(CONST_IMPL) SINGLE_ARG_FUNCS(SINGLE_ARG_IMPL) TWO_ARGS_FUNCS(TWO_ARGS_IMPL) POSITIVE_SINGLE_ARG_FUNCS(POSITIVE_SINGLE_ARG_IMPL) extern "C" UDF_ALWAYS_INLINE void SigmoidIR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { *result = TUnboxedValuePod(1. / (1. + exp(-args[0].Get()))); } extern "C" UDF_ALWAYS_INLINE void FuzzyEqualsIR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { if (!args[2]) { *result = TUnboxedValuePod(FuzzyEquals(args[0].Get(), args[1].Get())); } else { const double eps = args[2].Get(); *result = TUnboxedValuePod(FuzzyEquals(args[0].Get(), args[1].Get(), eps)); } } extern "C" UDF_ALWAYS_INLINE void RoundIR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { const double val = NMathUdf::RoundToDecimal(args[0].Get(), args[1].GetOrDefault(0)); *result = TUnboxedValuePod(val); } extern "C" UDF_ALWAYS_INLINE void ErfInvIR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { *result = TUnboxedValuePod(NMathUdf::ErfInv(args[0].Get())); } extern "C" UDF_ALWAYS_INLINE void ErfcInvIR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { *result = TUnboxedValuePod(NMathUdf::ErfInv(1. - args[0].Get())); } extern "C" UDF_ALWAYS_INLINE void ModIR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { const auto val = NMathUdf::Mod(args[0].Get(), args[1].Get()); *result = val ? TUnboxedValuePod(*val) : TUnboxedValuePod(); } extern "C" UDF_ALWAYS_INLINE void RemIR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { const auto val = NMathUdf::Rem(args[0].Get(), args[1].Get()); *result = val ? TUnboxedValuePod(*val) : TUnboxedValuePod(); } extern "C" UDF_ALWAYS_INLINE void NearbyIntIR(const IBoxedValue* /*pThis*/, TUnboxedValuePod* result, const IValueBuilder* /*valueBuilder*/, const TUnboxedValuePod* args) { const auto val = NMathUdf::NearbyInt(args[0].Get(), args[1].Get()); *result = val ? TUnboxedValuePod(*val) : TUnboxedValuePod(); } } // NUdf } // NYql