/*! * Copyright 2015 by Contributors * \file math.h * \brief additional math utils * \author Tianqi Chen */ #ifndef XGBOOST_COMMON_MATH_H_ #define XGBOOST_COMMON_MATH_H_ #include #include #include #include namespace xgboost { namespace common { /*! * \brief calculate the sigmoid of the input. * \param x input parameter * \return the transformed value. */ inline float Sigmoid(float x) { return 1.0f / (1.0f + std::exp(-x)); } /*! * \brief do inplace softmax transformaton on p_rec * \param p_rec the input/output vector of the values. */ inline void Softmax(std::vector* p_rec) { std::vector &rec = *p_rec; float wmax = rec[0]; for (size_t i = 1; i < rec.size(); ++i) { wmax = std::max(rec[i], wmax); } double wsum = 0.0f; for (size_t i = 0; i < rec.size(); ++i) { rec[i] = std::exp(rec[i] - wmax); wsum += rec[i]; } for (size_t i = 0; i < rec.size(); ++i) { rec[i] /= static_cast(wsum); } } /*! * \brief Find the maximum iterator within the iterators * \param begin The begining iterator. * \param end The end iterator. * \return the iterator point to the maximum value. * \tparam Iterator The type of the iterator. */ template inline Iterator FindMaxIndex(Iterator begin, Iterator end) { Iterator maxit = begin; for (Iterator it = begin; it != end; ++it) { if (*it > *maxit) maxit = it; } return maxit; } /*! * \brief perform numerically safe logsum * \param x left input operand * \param y right input operand * \return log(exp(x) + exp(y)) */ inline float LogSum(float x, float y) { if (x < y) { return y + std::log(std::exp(x - y) + 1.0f); } else { return x + std::log(std::exp(y - x) + 1.0f); } } /*! * \brief perform numerically safe logsum * \param begin The begining iterator. * \param end The end iterator. * \return the iterator point to the maximum value. * \tparam Iterator The type of the iterator. */ template inline float LogSum(Iterator begin, Iterator end) { float mx = *begin; for (Iterator it = begin; it != end; ++it) { mx = std::max(mx, *it); } float sum = 0.0f; for (Iterator it = begin; it != end; ++it) { sum += std::exp(*it - mx); } return mx + std::log(sum); } // comparator functions for sorting pairs in descending order inline static bool CmpFirst(const std::pair &a, const std::pair &b) { return a.first > b.first; } inline static bool CmpSecond(const std::pair &a, const std::pair &b) { return a.second > b.second; } #if XGBOOST_STRICT_R_MODE // check nan bool CheckNAN(double v); double LogGamma(double v); #else template inline bool CheckNAN(T v) { #ifdef _MSC_VER return (_isnan(v) != 0); #else return std::isnan(v); #endif } template inline T LogGamma(T v) { #ifdef _MSC_VER #if _MSC_VER >= 1800 return lgamma(v); #else #pragma message("Warning: lgamma function was not available until VS2013"\ ", poisson regression will be disabled") utils::Error("lgamma function was not available until VS2013"); return static_cast(1.0); #endif #else return lgamma(v); #endif } #endif // XGBOOST_STRICT_R_MODE_ } // namespace common } // namespace xgboost #endif // XGBOOST_COMMON_MATH_H_