| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifndef COLMAP_SRC_UTIL_MATH_H_ |
| | #define COLMAP_SRC_UTIL_MATH_H_ |
| |
|
| | #include <algorithm> |
| | #include <cmath> |
| | #include <complex> |
| | #include <limits> |
| | #include <list> |
| | #include <stdexcept> |
| | #include <vector> |
| |
|
| | #include "util/logging.h" |
| |
|
| | #ifndef M_PI |
| | #define M_PI 3.14159265358979323846264338327950288 |
| | #endif |
| |
|
| | namespace colmap { |
| |
|
| | |
| | template <typename T> |
| | int SignOfNumber(const T val); |
| |
|
| | |
| | inline bool IsNaN(const float x); |
| | inline bool IsNaN(const double x); |
| |
|
| | |
| | inline bool IsInf(const float x); |
| | inline bool IsInf(const double x); |
| |
|
| | |
| | template <typename T> |
| | inline T Clip(const T& value, const T& low, const T& high); |
| |
|
| | |
| | inline float DegToRad(const float deg); |
| | inline double DegToRad(const double deg); |
| |
|
| | |
| | inline float RadToDeg(const float rad); |
| | inline double RadToDeg(const double rad); |
| |
|
| | |
| | template <typename T> |
| | double Median(const std::vector<T>& elems); |
| |
|
| | |
| | template <typename T> |
| | double Mean(const std::vector<T>& elems); |
| |
|
| | |
| | template <typename T> |
| | double Variance(const std::vector<T>& elems); |
| |
|
| | |
| | template <typename T> |
| | double StdDev(const std::vector<T>& elems); |
| |
|
| | |
| | template <typename T> |
| | bool AnyLessThan(std::vector<T> elems, T threshold); |
| |
|
| | |
| | template <typename T> |
| | bool AnyGreaterThan(std::vector<T> elems, T threshold); |
| |
|
| | |
| | |
| | |
| | |
| | template <class Iterator> |
| | bool NextCombination(Iterator first, Iterator middle, Iterator last); |
| |
|
| | |
| | template <typename T> |
| | T Sigmoid(const T x, const T alpha = 1); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <typename T> |
| | T ScaleSigmoid(T x, const T alpha = 1, const T x0 = 10); |
| |
|
| | |
| | size_t NChooseK(const size_t n, const size_t k); |
| |
|
| | |
| | |
| | template <typename T1, typename T2> |
| | T2 TruncateCast(const T1 value); |
| |
|
| | |
| | template <typename T> |
| | T Percentile(const std::vector<T>& elems, const double p); |
| |
|
| | |
| | |
| | |
| |
|
| | namespace internal { |
| |
|
| | template <class Iterator> |
| | bool NextCombination(Iterator first1, Iterator last1, Iterator first2, |
| | Iterator last2) { |
| | if ((first1 == last1) || (first2 == last2)) { |
| | return false; |
| | } |
| | Iterator m1 = last1; |
| | Iterator m2 = last2; |
| | --m2; |
| | while (--m1 != first1 && *m1 >= *m2) { |
| | } |
| | bool result = (m1 == first1) && *first1 >= *m2; |
| | if (!result) { |
| | while (first2 != m2 && *m1 >= *first2) { |
| | ++first2; |
| | } |
| | first1 = m1; |
| | std::iter_swap(first1, first2); |
| | ++first1; |
| | ++first2; |
| | } |
| | if ((first1 != last1) && (first2 != last2)) { |
| | m1 = last1; |
| | m2 = first2; |
| | while ((m1 != first1) && (m2 != last2)) { |
| | std::iter_swap(--m1, m2); |
| | ++m2; |
| | } |
| | std::reverse(first1, m1); |
| | std::reverse(first1, last1); |
| | std::reverse(m2, last2); |
| | std::reverse(first2, last2); |
| | } |
| | return !result; |
| | } |
| |
|
| | } |
| |
|
| | template <typename T> |
| | int SignOfNumber(const T val) { |
| | return (T(0) < val) - (val < T(0)); |
| | } |
| |
|
| | bool IsNaN(const float x) { return x != x; } |
| | bool IsNaN(const double x) { return x != x; } |
| |
|
| | bool IsInf(const float x) { return !IsNaN(x) && IsNaN(x - x); } |
| | bool IsInf(const double x) { return !IsNaN(x) && IsNaN(x - x); } |
| |
|
| | template <typename T> |
| | T Clip(const T& value, const T& low, const T& high) { |
| | return std::max(low, std::min(value, high)); |
| | } |
| |
|
| | float DegToRad(const float deg) { |
| | return deg * 0.0174532925199432954743716805978692718781530857086181640625f; |
| | } |
| |
|
| | double DegToRad(const double deg) { |
| | return deg * 0.0174532925199432954743716805978692718781530857086181640625; |
| | } |
| |
|
| | |
| | float RadToDeg(const float rad) { |
| | return rad * 57.29577951308232286464772187173366546630859375f; |
| | } |
| |
|
| | double RadToDeg(const double rad) { |
| | return rad * 57.29577951308232286464772187173366546630859375; |
| | } |
| |
|
| | template <typename T> |
| | double Median(const std::vector<T>& elems) { |
| | CHECK(!elems.empty()); |
| |
|
| | const size_t mid_idx = elems.size() / 2; |
| |
|
| | std::vector<T> ordered_elems = elems; |
| | std::nth_element(ordered_elems.begin(), ordered_elems.begin() + mid_idx, |
| | ordered_elems.end()); |
| |
|
| | if (elems.size() % 2 == 0) { |
| | const T mid_element1 = ordered_elems[mid_idx]; |
| | const T mid_element2 = *std::max_element(ordered_elems.begin(), |
| | ordered_elems.begin() + mid_idx); |
| | return (mid_element1 + mid_element2) / 2.0; |
| | } else { |
| | return ordered_elems[mid_idx]; |
| | } |
| | } |
| |
|
| | template <typename T> |
| | T Percentile(const std::vector<T>& elems, const double p) { |
| | CHECK(!elems.empty()); |
| | CHECK_GE(p, 0); |
| | CHECK_LE(p, 100); |
| |
|
| | const int idx = static_cast<int>(std::round(p / 100 * (elems.size() - 1))); |
| | const size_t percentile_idx = |
| | std::max(0, std::min(static_cast<int>(elems.size() - 1), idx)); |
| |
|
| | std::vector<T> ordered_elems = elems; |
| | std::nth_element(ordered_elems.begin(), |
| | ordered_elems.begin() + percentile_idx, ordered_elems.end()); |
| |
|
| | return ordered_elems.at(percentile_idx); |
| | } |
| |
|
| | template <typename T> |
| | double Mean(const std::vector<T>& elems) { |
| | CHECK(!elems.empty()); |
| | double sum = 0; |
| | for (const auto el : elems) { |
| | sum += static_cast<double>(el); |
| | } |
| | return sum / elems.size(); |
| | } |
| |
|
| | template <typename T> |
| | double Variance(const std::vector<T>& elems) { |
| | const double mean = Mean(elems); |
| | double var = 0; |
| | for (const auto el : elems) { |
| | const double diff = el - mean; |
| | var += diff * diff; |
| | } |
| | return var / (elems.size() - 1); |
| | } |
| |
|
| | template <typename T> |
| | double StdDev(const std::vector<T>& elems) { |
| | return std::sqrt(Variance(elems)); |
| | } |
| |
|
| | template <typename T> |
| | bool AnyLessThan(std::vector<T> elems, T threshold) { |
| | for (const auto& el : elems) { |
| | if (el < threshold) { |
| | return true; |
| | } |
| | } |
| | return false; |
| | } |
| |
|
| | template <typename T> |
| | bool AnyGreaterThan(std::vector<T> elems, T threshold) { |
| | for (const auto& el : elems) { |
| | if (el > threshold) { |
| | return true; |
| | } |
| | } |
| | return false; |
| | } |
| |
|
| | template <class Iterator> |
| | bool NextCombination(Iterator first, Iterator middle, Iterator last) { |
| | return internal::NextCombination(first, middle, middle, last); |
| | } |
| |
|
| | template <typename T> |
| | T Sigmoid(const T x, const T alpha) { |
| | return T(1) / (T(1) + exp(-x * alpha)); |
| | } |
| |
|
| | template <typename T> |
| | T ScaleSigmoid(T x, const T alpha, const T x0) { |
| | const T t0 = Sigmoid(-x0, alpha); |
| | const T t1 = Sigmoid(x0, alpha); |
| | x = (Sigmoid(2 * x0 * x - x0, alpha) - t0) / (t1 - t0); |
| | return x; |
| | } |
| |
|
| | template <typename T1, typename T2> |
| | T2 TruncateCast(const T1 value) { |
| | return std::min( |
| | static_cast<T1>(std::numeric_limits<T2>::max()), |
| | std::max(static_cast<T1>(std::numeric_limits<T2>::min()), value)); |
| | } |
| |
|
| | } |
| |
|
| | #endif |
| |
|