<commit_before>/**
 * @file
 */
#pragma once

#include "numbirch/type.hpp"

/* for recent versions of CUDA, disables warnings about diag_suppress being
 * deprecated in favor of nv_diag_suppress */
#pragma nv_diag_suppress 20236

#if defined(HAVE_UNSUPPORTED_EIGEN_SPECIALFUNCTIONS)
#include <unsupported/Eigen/SpecialFunctions>
#elif defined(HAVE_EIGEN3_UNSUPPORTED_EIGEN_SPECIALFUNCTIONS)
#include <eigen3/unsupported/Eigen/SpecialFunctions>
#endif

namespace numbirch {
static const long double PI = 3.1415926535897932384626433832795;

template<class T>
struct identity_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return x;
  }
};

template<class T>
struct negate_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return -x;
  }
};

template<class T>
struct add_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x + y;
  }
};

template<class T>
struct subtract_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x - y;
  }
};

template<class T>
struct multiply_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x*y;
  }
};

template<class T>
struct divide_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x/y;
  }
};

template<class T>
struct not_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return !x;
  }
};

template<class T>
struct and_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x && y;
  }
};

template<class T>
struct or_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x || y;
  }
};

template<class T>
struct equal_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x == y;
  }
};

template<class T>
struct not_equal_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x != y;
  }
};

template<class T>
struct less_functor {
  NUMBIRCH_HOST_DEVICE bool operator()(const T x, const T y) const {
    return x < y;
  }
};

template<class T>
struct less_or_equal_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x <= y;
  }
};

template<class T>
struct greater_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x > y;
  }
};

template<class T>
struct greater_or_equal_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x >= y;
  }
};

template<class T>
struct abs_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::abs(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct acos_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::acos(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct asin_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::asin(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct atan_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::atan(x);
  }
};

template<class T>
struct ceil_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    if constexpr (is_integral_v<T>) {
      return x;
    } else {
      return std::ceil(x);
    }
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct cos_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::cos(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct cosh_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::cosh(x);
  }
};

template<class T>
struct count_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return (x == 0) ? 0 : 1;
  }
};

template<class T, class U>
struct diagonal_functor {
  diagonal_functor(const U a) :
      a(a) {
    //
  }
  NUMBIRCH_HOST_DEVICE auto operator()(const int i, const int j) const {
    return (i == j) ? T(element(a)) : 0;
  }
  const U a;
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct digamma_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return Eigen::numext::digamma(x);
  }
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    T z = 0;
    for (T i = 1; i <= y; ++i) {
      z += Eigen::numext::digamma(x + T(0.5)*(1 - i));
    }
    return z;
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct exp_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::exp(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct expm1_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::expm1(x);
  }
};

template<class T>
struct floor_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    if constexpr (is_integral_v<T>) {
      return x;
    } else {
      return std::floor(x);
    }
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lfact_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::lgamma(x + T(1));
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lfact_grad_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T g, const T x) const {
    return g*Eigen::numext::digamma(x + T(1));
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lgamma_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::lgamma(x);
  }
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    T z = T(0.25)*y*(y - T(1))*std::log(T(PI));
    for (T i = T(1); i <= y; ++i) {
      z += std::lgamma(x + T(0.5)*(T(1) - i));
    }
    return z;
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct log_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::log(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct log1p_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::log1p(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct log_abs_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::log(std::abs(x));
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct log_square_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return T(2)*std::log(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct rcp_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return T(1)/x;
  }
};

template<class T>
struct rectify_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::max(T(0), x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct rectify_grad_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T g, const T x) const {
    return (x > T(0)) ? g : T(0);
  }
};

template<class T>
struct round_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    if constexpr (is_integral_v<T>) {
      return x;
    } else {
      return std::round(x);
    }
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct sin_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::sin(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct sinh_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::sinh(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct sqrt_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::sqrt(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct tan_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::tan(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct tanh_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::tanh(x);
  }
};

template<class T>
struct copysign_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    if constexpr (is_integral_v<T>) {
      // don't use std::copysign, as it promotes to floating point, which
      // we don't wish to do here
      return (y >= T(0)) ? std::abs(x) : -std::abs(x);
    } else {
      return std::copysign(x, y);
    }
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct gamma_p_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T a, const T x) const {
    return Eigen::numext::igamma(a, x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct gamma_q_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T a, const T x) const {
    return Eigen::numext::igammac(a, x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lbeta_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return std::lgamma(x) + std::lgamma(y) - std::lgamma(x + y);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lchoose_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const int x, const int y) const {
    return std::lgamma(x + T(1)) - std::lgamma(y + T(1)) - std::lgamma(x - y);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lchoose_grad_functor {
  NUMBIRCH_HOST_DEVICE pair<T,T> operator()(const T g, const T x, const T y)
      const {
    T gx = Eigen::numext::digamma(x + T(1)) -
        Eigen::numext::digamma(x - y + T(1));
    T gy = -Eigen::numext::digamma(y + T(1)) +
        Eigen::numext::digamma(x - y + T(1));
    return pair<T,T>{g*gx, g*gy};
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct pow_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return std::pow(x, y);
  }
};

template<class T, class U, class V = int>
struct single_functor {
  single_functor(const U k, const V l = 1) :
      k(k), l(l) {
    //
  }
  NUMBIRCH_HOST_DEVICE T operator()(const int i, const int j) const {
    return (i == element(k) - 1 && j == element(l) - 1) ? T(1) : T(0);
  }
  const U k;
  const V l;
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct ibeta_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T a, const T b, const T x) const {
    /* as of Eigen 3.4.0, the edge cases of a == 0 and b == 0 are not handled
    * internally, see https://gitlab.com/libeigen/eigen/-/issues/2359 */
    if (a == T(0) && b != T(0)) {
      return T(1);
    } else if (a != T(0) && b == T(0)) {
      return T(0);
    } else {
      return Eigen::numext::betainc(a, b, x);
    }
  }
};

}
<commit_msg>Fixed lchoose().<commit_after>/**
 * @file
 */
#pragma once

#include "numbirch/type.hpp"

/* for recent versions of CUDA, disables warnings about diag_suppress being
 * deprecated in favor of nv_diag_suppress */
#pragma nv_diag_suppress 20236

#if defined(HAVE_UNSUPPORTED_EIGEN_SPECIALFUNCTIONS)
#include <unsupported/Eigen/SpecialFunctions>
#elif defined(HAVE_EIGEN3_UNSUPPORTED_EIGEN_SPECIALFUNCTIONS)
#include <eigen3/unsupported/Eigen/SpecialFunctions>
#endif

namespace numbirch {
static const long double PI = 3.1415926535897932384626433832795;

template<class T>
struct identity_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return x;
  }
};

template<class T>
struct negate_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return -x;
  }
};

template<class T>
struct add_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x + y;
  }
};

template<class T>
struct subtract_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x - y;
  }
};

template<class T>
struct multiply_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x*y;
  }
};

template<class T>
struct divide_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x/y;
  }
};

template<class T>
struct not_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return !x;
  }
};

template<class T>
struct and_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x && y;
  }
};

template<class T>
struct or_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x || y;
  }
};

template<class T>
struct equal_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x == y;
  }
};

template<class T>
struct not_equal_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x != y;
  }
};

template<class T>
struct less_functor {
  NUMBIRCH_HOST_DEVICE bool operator()(const T x, const T y) const {
    return x < y;
  }
};

template<class T>
struct less_or_equal_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x <= y;
  }
};

template<class T>
struct greater_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x > y;
  }
};

template<class T>
struct greater_or_equal_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return x >= y;
  }
};

template<class T>
struct abs_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::abs(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct acos_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::acos(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct asin_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::asin(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct atan_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::atan(x);
  }
};

template<class T>
struct ceil_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    if constexpr (is_integral_v<T>) {
      return x;
    } else {
      return std::ceil(x);
    }
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct cos_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::cos(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct cosh_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::cosh(x);
  }
};

template<class T>
struct count_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return (x == 0) ? 0 : 1;
  }
};

template<class T, class U>
struct diagonal_functor {
  diagonal_functor(const U a) :
      a(a) {
    //
  }
  NUMBIRCH_HOST_DEVICE auto operator()(const int i, const int j) const {
    return (i == j) ? T(element(a)) : 0;
  }
  const U a;
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct digamma_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return Eigen::numext::digamma(x);
  }
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    T z = 0;
    for (T i = 1; i <= y; ++i) {
      z += Eigen::numext::digamma(x + T(0.5)*(1 - i));
    }
    return z;
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct exp_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::exp(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct expm1_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::expm1(x);
  }
};

template<class T>
struct floor_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    if constexpr (is_integral_v<T>) {
      return x;
    } else {
      return std::floor(x);
    }
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lfact_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::lgamma(x + T(1));
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lfact_grad_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T g, const T x) const {
    return g*Eigen::numext::digamma(x + T(1));
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lgamma_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::lgamma(x);
  }
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    T z = T(0.25)*y*(y - T(1))*std::log(T(PI));
    for (T i = T(1); i <= y; ++i) {
      z += std::lgamma(x + T(0.5)*(T(1) - i));
    }
    return z;
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct log_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::log(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct log1p_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::log1p(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct log_abs_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::log(std::abs(x));
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct log_square_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return T(2)*std::log(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct rcp_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return T(1)/x;
  }
};

template<class T>
struct rectify_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::max(T(0), x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct rectify_grad_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T g, const T x) const {
    return (x > T(0)) ? g : T(0);
  }
};

template<class T>
struct round_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    if constexpr (is_integral_v<T>) {
      return x;
    } else {
      return std::round(x);
    }
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct sin_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::sin(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct sinh_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::sinh(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct sqrt_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::sqrt(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct tan_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::tan(x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct tanh_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x) const {
    return std::tanh(x);
  }
};

template<class T>
struct copysign_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    if constexpr (is_integral_v<T>) {
      // don't use std::copysign, as it promotes to floating point, which
      // we don't wish to do here
      return (y >= T(0)) ? std::abs(x) : -std::abs(x);
    } else {
      return std::copysign(x, y);
    }
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct gamma_p_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T a, const T x) const {
    return Eigen::numext::igamma(a, x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct gamma_q_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T a, const T x) const {
    return Eigen::numext::igammac(a, x);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lbeta_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return std::lgamma(x) + std::lgamma(y) - std::lgamma(x + y);
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lchoose_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const int x, const int y) const {
    return std::lgamma(x + T(1)) - std::lgamma(y + T(1)) -
        std::lgamma(x - y + T(1));
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct lchoose_grad_functor {
  NUMBIRCH_HOST_DEVICE pair<T,T> operator()(const T g, const T x, const T y)
      const {
    T gx = Eigen::numext::digamma(x + T(1)) -
        Eigen::numext::digamma(x - y + T(1));
    T gy = -Eigen::numext::digamma(y + T(1)) +
        Eigen::numext::digamma(x - y + T(1));
    return pair<T,T>{g*gx, g*gy};
  }
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct pow_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T x, const T y) const {
    return std::pow(x, y);
  }
};

template<class T, class U, class V = int>
struct single_functor {
  single_functor(const U k, const V l = 1) :
      k(k), l(l) {
    //
  }
  NUMBIRCH_HOST_DEVICE T operator()(const int i, const int j) const {
    return (i == element(k) - 1 && j == element(l) - 1) ? T(1) : T(0);
  }
  const U k;
  const V l;
};

template<class T, class = std::enable_if_t<is_floating_point_v<T>,int>>
struct ibeta_functor {
  NUMBIRCH_HOST_DEVICE T operator()(const T a, const T b, const T x) const {
    /* as of Eigen 3.4.0, the edge cases of a == 0 and b == 0 are not handled
    * internally, see https://gitlab.com/libeigen/eigen/-/issues/2359 */
    if (a == T(0) && b != T(0)) {
      return T(1);
    } else if (a != T(0) && b == T(0)) {
      return T(0);
    } else {
      return Eigen::numext::betainc(a, b, x);
    }
  }
};

}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>

#include <stdint.h>

#include <iostream>
#include <fstream>
#include <vector>

/********************  SETTINGS  ********************/
// SDIO Settings
#define BLOCK_SIZE              512ULL   /* SD card block size in Bytes (512 for a normal SD card) */

// Logger settings
#define RX_BUFFER_NUM_BLOCKS    20ULL /* 20 blocks * 512 = 10 KB RAM required per buffer*/

// SD Card size
#define SDCARD_SIZE	(8ULL*1024ULL*1024ULL*1024ULL)

/**************   END OF SETTINGS   *****************/

#define BUFF_SIZE  (BLOCK_SIZE*RX_BUFFER_NUM_BLOCKS)

void read_disk_raw(char* volume_name, uint64_t disk_size);

inline void wordswap(int32_t *i)
{
	uint8_t *p = (uint8_t*) i;
	uint8_t tmp = p[0];
	p[0] = p[1];
	p[1] = tmp;
	tmp = p[2];
	p[2] = p[3];
	p[3] = tmp;
}

int main(int argc, char** argv)
{
    printf("PARSE DISK:\n----------\n");
	printf("highspeedloggerbinaryparser <DRIVE>     : eg. '/dev/sdb' or '\\\\.\\G:'  \n");
	printf("highspeedloggerbinaryparser <DUMPFILE>  : eg. foo.diskdump \n\n");

	if (argc >= 2)
	{

		if (argc == 2)
		{
			read_disk_raw(argv[1], SDCARD_SIZE);
			exit(0);
		}
	}
	else
	{

#ifdef WIN32
		read_disk_raw("\\\\.\\G:", SDCARD_SIZE);
	    // read_disk_raw("d:\\cessnaLogFull.dd", SDCARD_SIZE);
#else
	//long long disk_size;
	//ioctl(<disk_fd>, BLKGETSIZE64, &disk_size);
		read_disk_raw("/dev/sdb", SDCARD_SIZE);
#endif

		exit(0);
	}

	exit(-1);
}

#if 0

#define WIN32_LEAN_AND_MEAN
#define BUFFER_SIZE 32

#include <windows.h>

void read_disk_raw(void)
{
	HANDLE hFile;
	DWORD dwBytesRead = 0;
	char ReadBuffer[BUFFER_SIZE] = {0};

	hFile = CreateFile("\\\\.\\G:",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

	if (hFile == INVALID_HANDLE_VALUE)
	{
		printf("Could not open file (error %d)\n", GetLastError());
		return;
	}

	// Read one character less than the buffer size to save room for
	// the terminating NULL character.

	if( FALSE == ReadFile(hFile, ReadBuffer, BUFFER_SIZE-2, &dwBytesRead, NULL) )
	{
		printf("Could not read from file (error %d)\n", GetLastError());
		CloseHandle(hFile);
		return;
	}

	if (dwBytesRead > 0)
	{
		ReadBuffer[dwBytesRead+1]='\0'; // NULL character

		printf(TEXT("Text read from %s (%d bytes): \n"), dwBytesRead);
		printf("%s\n", ReadBuffer);
	}
	else
	{
		printf(TEXT("No data read from file %s\n"));
	}

	CloseHandle(hFile);

}

#endif

void scan_all_blocks(FILE* volume, uint64_t disk_size);

// Read from sector //
void read_disk_raw(char* volume_name, uint64_t disk_size)
{
    FILE *volume;
    int k = 0;

	uint64_t sd = disk_size;
	sd /= 1024UL * 1024UL;
	printf("\nExpecting an SD-card of %lu MB.\n",sd);

    volume = fopen(volume_name, "r+b");
    if(!volume)
    {
        printf("Cant open Drive '%s'\n", volume_name);
        return;
    }
    setbuf(volume, NULL);       // Disable buffering

	printf("\nSearching for logfiles in '%s': \n...\r",volume_name);

	scan_all_blocks(volume, disk_size);

    fclose(volume);
 }

void scan_all_blocks(FILE* volume, uint64_t disk_size)
{
    char buf[BUFF_SIZE] = {0};

	int log = -1;
	int cnt = 0;

	FILE* of = 0;

	uint64_t addr = 0;
	while (addr < disk_size)
	{
		if(_fseeki64(volume, addr, SEEK_SET) != 0)
		{
			printf("Cant move to sector\n");
			return;
		}

		// Read BLOCK
		size_t r = fread(buf, 1, BUFF_SIZE, volume);

		// Start of block must contain <CODE 1A 1B 1C>
		if (  ((unsigned char)buf[0] == 0x1a) && ((unsigned char)buf[1] == 0x1b) && ((unsigned char)buf[2] == 0x1c))
        {
			/////////////////////////////////////////////////
			// Start of new Logfile
            if ((unsigned char)buf[3] == 0xaa)
            {
				int tt = 0;
				int nr = 0;
				tt = (int) ((uint8_t)buf[6]);
				nr = (int)  ((uint8_t) buf[5] ) + ((uint16_t) buf[4] )*256;
				char filename[32];
				char logtype[16];
				log++;
				switch(tt)
				{
				case 0:
					sprintf(logtype, "SPI1");
					break;
				case 1:
					sprintf(logtype, "SPI2");
					break;
				case 2:
					sprintf(logtype, "UART2");
					break;
				case 3:
					sprintf(logtype, "UART3");
					break;
				default:
					sprintf(logtype, "UNKNOWN");
					break;
				}
				sprintf(filename, "sd_hs_log_%05d_%s.bin", log, logtype);
				if (of > 0)
				{
					fclose(of);
					of = 0;
				}
				of = fopen(filename, "w+b");
				fwrite(buf,1,BUFF_SIZE,of);
				if (log > 0)
					printf("%d x 10k\nLog %d [#%d]: type [%x=%s] addr: <%ld> ",cnt, log, nr, tt, logtype, addr/1024);
				else
	                printf("Log %d [#%d]: type [%x=%s] addr: <%ld> ",log, nr, tt, logtype, addr/1024);
				cnt = 0;
            }
			/////////////////////////////////////////////////
			// Continued Logfile
            else if ((unsigned char)buf[3] == 0xbb)
            {
				cnt++;
				if (of > 0)
					fwrite(buf,1,BUFF_SIZE,of);

            }
            else
            {
				if (of > 0)
				{
					fclose(of);
					of = 0;
				}
                printf("? (%x)",(unsigned char)buf[3]);
            }
        }
        else
        {
			if (of > 0)
			{
				fclose(of);
				of = 0;
			}
			if (cnt > 0)
			{
				printf("%d x 10k\nFound End <%ld>\n",cnt, addr/1024);
				cnt = 0;
				break;
				//addr = disk_size;
			}
			else
			{
				//printf("Cnt ==0\n");
			}
    		//printf(".");
        }

		int f = feof(volume);
		int e = ferror(volume);

		if (f!=0)
		{
			printf("%d x 10k\nEof <%ld>\n",cnt, addr/1024);
			cnt = 0;
			break;
		}

		addr += BUFF_SIZE;

		if (addr >= disk_size) {
			printf("End of disk: cnt=%d <%ld><%ld>\n",cnt,addr,disk_size);
		}

		//printf("\n %ld: %d %d %d ",addr, f, e, r);
	}

    // Print out what wiat in sector //
    // for(k=0;k<BUFFER_SIZE;k++)
    //    printf("%02x ", (unsigned char) buf[k]);

}

<commit_msg>ask SD card size (Linux only)<commit_after>#include <stdio.h>
#include <stdlib.h>

#include <stdint.h>

#include <iostream>
#include <fstream>
#include <vector>

/********************  SETTINGS  ********************/
// SDIO Settings
#define BLOCK_SIZE              512ULL   /* SD card block size in Bytes (512 for a normal SD card) */

// Logger settings
#define RX_BUFFER_NUM_BLOCKS    20ULL /* 20 blocks * 512 = 10 KB RAM required per buffer*/

// SD Card size
#define SDCARD_SIZE	(8ULL*1024ULL*1024ULL*1024ULL)

/**************   END OF SETTINGS   *****************/

#define BUFF_SIZE  (BLOCK_SIZE*RX_BUFFER_NUM_BLOCKS)

void read_disk_raw(char* volume_name, uint64_t disk_size);

inline void wordswap(int32_t *i)
{
	uint8_t *p = (uint8_t*) i;
	uint8_t tmp = p[0];
	p[0] = p[1];
	p[1] = tmp;
	tmp = p[2];
	p[2] = p[3];
	p[3] = tmp;
}

int main(int argc, char** argv)
{
    printf("PARSE DISK:\n----------\n");
	printf("highspeedloggerbinaryparser <DRIVE>     : eg. '/dev/sdb' or '\\\\.\\G:'  \n");
	printf("highspeedloggerbinaryparser <DUMPFILE>  : eg. foo.diskdump \n\n");

	if (argc >= 2)
	{

		if (argc == 2)
		{
			read_disk_raw(argv[1], SDCARD_SIZE);
			exit(0);
		}
	}
	else
	{

#ifdef WIN32
		read_disk_raw("\\\\.\\G:", SDCARD_SIZE);
	    // read_disk_raw("d:\\cessnaLogFull.dd", SDCARD_SIZE);
#else
		read_disk_raw("/dev/sdb", SDCARD_SIZE);
#endif

		exit(0);
	}

	exit(-1);
}

#if 0

#define WIN32_LEAN_AND_MEAN
#define BUFFER_SIZE 32

#include <windows.h>

void read_disk_raw(void)
{
	HANDLE hFile;
	DWORD dwBytesRead = 0;
	char ReadBuffer[BUFFER_SIZE] = {0};

	hFile = CreateFile("\\\\.\\G:",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

	if (hFile == INVALID_HANDLE_VALUE)
	{
		printf("Could not open file (error %d)\n", GetLastError());
		return;
	}

	// Read one character less than the buffer size to save room for
	// the terminating NULL character.

	if( FALSE == ReadFile(hFile, ReadBuffer, BUFFER_SIZE-2, &dwBytesRead, NULL) )
	{
		printf("Could not read from file (error %d)\n", GetLastError());
		CloseHandle(hFile);
		return;
	}

	if (dwBytesRead > 0)
	{
		ReadBuffer[dwBytesRead+1]='\0'; // NULL character

		printf(TEXT("Text read from %s (%d bytes): \n"), dwBytesRead);
		printf("%s\n", ReadBuffer);
	}
	else
	{
		printf(TEXT("No data read from file %s\n"));
	}

	CloseHandle(hFile);

}

#endif

void scan_all_blocks(FILE* volume, uint64_t disk_size);

// Read from sector //
void read_disk_raw(char* volume_name, uint64_t disk_size)
{
    FILE *volume;
    int k = 0;

    volume = fopen(volume_name, "r+b");
    if(!volume)
    {
        printf("Cant open Drive '%s'\n", volume_name);
        return;
    }
    setbuf(volume, NULL);       // Disable buffering

#ifdef WIN32
	uint64_t sd = disk_size;
	sd /= 1024UL * 1024UL;
	printf("\nExpecting an SD-card of %lu MB.\n",sd);
#else
	long long sdcard_disk_size;
	ioctl(volume, BLKGETSIZE64, &sdcard_disk_size);
	disk_size /= 1024ULL * 1024 ULL;
	printf("Found an SG card of %lld:",sdcard_disk_size);
#endif

	printf("\nSearching for logfiles in '%s': \n...\r",volume_name);

	scan_all_blocks(volume, disk_size);

    fclose(volume);
 }

void scan_all_blocks(FILE* volume, uint64_t disk_size)
{
    char buf[BUFF_SIZE] = {0};

	int log = -1;
	int cnt = 0;

	FILE* of = 0;

	uint64_t addr = 0;
	while (addr < disk_size)
	{
		if(_fseeki64(volume, addr, SEEK_SET) != 0)
		{
			printf("Cant move to sector\n");
			return;
		}

		// Read BLOCK
		size_t r = fread(buf, 1, BUFF_SIZE, volume);

		// Start of block must contain <CODE 1A 1B 1C>
		if (  ((unsigned char)buf[0] == 0x1a) && ((unsigned char)buf[1] == 0x1b) && ((unsigned char)buf[2] == 0x1c))
        {
			/////////////////////////////////////////////////
			// Start of new Logfile
            if ((unsigned char)buf[3] == 0xaa)
            {
				int tt = 0;
				int nr = 0;
				tt = (int) ((uint8_t)buf[6]);
				nr = (int)  ((uint8_t) buf[5] ) + ((uint16_t) buf[4] )*256;
				char filename[32];
				char logtype[16];
				log++;
				switch(tt)
				{
				case 0:
					sprintf(logtype, "SPI1");
					break;
				case 1:
					sprintf(logtype, "SPI2");
					break;
				case 2:
					sprintf(logtype, "UART2");
					break;
				case 3:
					sprintf(logtype, "UART3");
					break;
				default:
					sprintf(logtype, "UNKNOWN");
					break;
				}
				sprintf(filename, "sd_hs_log_%05d_%s.bin", log, logtype);
				if (of > 0)
				{
					fclose(of);
					of = 0;
				}
				of = fopen(filename, "w+b");
				fwrite(buf,1,BUFF_SIZE,of);
				if (log > 0)
					printf("%d x 10k\nLog %d [#%d]: type [%x=%s] addr: <%ld> ",cnt, log, nr, tt, logtype, addr/1024);
				else
	                printf("Log %d [#%d]: type [%x=%s] addr: <%ld> ",log, nr, tt, logtype, addr/1024);
				cnt = 0;
            }
			/////////////////////////////////////////////////
			// Continued Logfile
            else if ((unsigned char)buf[3] == 0xbb)
            {
				cnt++;
				if (of > 0)
					fwrite(buf,1,BUFF_SIZE,of);

            }
            else
            {
				if (of > 0)
				{
					fclose(of);
					of = 0;
				}
                printf("? (%x)",(unsigned char)buf[3]);
            }
        }
        else
        {
			if (of > 0)
			{
				fclose(of);
				of = 0;
			}
			if (cnt > 0)
			{
				printf("%d x 10k\nFound End <%ld>\n",cnt, addr/1024);
				cnt = 0;
				break;
				//addr = disk_size;
			}
			else
			{
				//printf("Cnt ==0\n");
			}
    		//printf(".");
        }

		int f = feof(volume);
		int e = ferror(volume);

		if (f!=0)
		{
			printf("%d x 10k\nEof <%ld>\n",cnt, addr/1024);
			cnt = 0;
			break;
		}

		addr += BUFF_SIZE;

		if (addr >= disk_size) {
			printf("End of disk: cnt=%d <%ld><%ld>\n",cnt,addr,disk_size);
		}

		//printf("\n %ld: %d %d %d ",addr, f, e, r);
	}

    // Print out what wiat in sector //
    // for(k=0;k<BUFFER_SIZE;k++)
    //    printf("%02x ", (unsigned char) buf[k]);

}

<|endoftext|>


<commit_before><commit_msg>Don't show pre-sm_20 CUDA cards in the device list<commit_after><|endoftext|>


<commit_before>// stdafx1.cpp : source file that includes just the standard includes
//  stdafx1.pch will be the pre-compiled header
//  stdafx1.obj will contain the pre-compiled type information

#include "stdafx2.h"

#ifdef _ATL_STATIC_REGISTRY
#include <statreg.h>
#include <statreg.cpp>
#endif

#include <atlimpl.cpp>
<commit_msg>INTEGRATION: CWS sdk04 (1.1.62); FILE MERGED 2003/06/24 11:10:03 jsc 1.1.62.1: #110313# insert source license header<commit_after>/*************************************************************************
 *
 *  $RCSfile: StdAfx2.cpp,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2003-06-30 15:50:20 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  the BSD license.
 *
 *  Copyright (c) 2003 by Sun Microsystems, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *************************************************************************/

// stdafx1.cpp : source file that includes just the standard includes
//  stdafx1.pch will be the pre-compiled header
//  stdafx1.obj will contain the pre-compiled type information

#include "stdafx2.h"

#ifdef _ATL_STATIC_REGISTRY
#include <statreg.h>
#include <statreg.cpp>
#endif

#include <atlimpl.cpp>
<|endoftext|>


<commit_before>
#include "FaceTracker.hpp"
#include <exception>
#include <cmath>
#include <stdio.h>

using namespace std;

namespace YerFace {

FaceTracker::FaceTracker(string myClassifierFileName, FrameDerivatives *myFrameDerivatives, float myTrackingBoxPercentage, float myMaxFaceSizePercentage, int myOpticalTrackStaleFramesInterval) {
	classifierFileName = myClassifierFileName;
	frameDerivatives = myFrameDerivatives;
	trackerState = DETECTING;
	classificationBoxSet = false;
	trackingBoxSet = false;

	trackingBoxPercentage = myTrackingBoxPercentage;
	if(trackingBoxPercentage <= 0.0 || trackingBoxPercentage > 1.0) {
		throw invalid_argument("trackingBoxPercentage is out of range.");
	}
	maxFaceSizePercentage = myMaxFaceSizePercentage;
	if(maxFaceSizePercentage <= 0.0 || maxFaceSizePercentage > 1.0) {
		throw invalid_argument("maxFaceSizePercentage is out of range.");
	}
	opticalTrackStaleFramesInterval = myOpticalTrackStaleFramesInterval;
	if(opticalTrackStaleFramesInterval <= 0) {
		throw invalid_argument("opticalTrackStaleFramesInterval is out of range.");
	}
	if(!cascadeClassifier.load(classifierFileName)) {
		throw invalid_argument("Unable to load specified classifier.");
	}
	fprintf(stderr, "FaceTracker object constructed and ready to go!\n");
}

TrackerState FaceTracker::processCurrentFrame(void) {
	if(trackerState == DETECTING || trackerState == LOST || trackerState == STALE) {
		classificationBoxSet = false;
		std::vector<Rect> faces;
		Mat classificationFrame = frameDerivatives->getClassificationFrame();
		double classificationFrameArea = (double)classificationFrame.size().area();
		double maxFaceSize = sqrt(classificationFrameArea * maxFaceSizePercentage);
		cascadeClassifier.detectMultiScale(classificationFrame, faces, 1.1, 3, 0|CASCADE_SCALE_IMAGE, Size(maxFaceSize, maxFaceSize));

		int largestFace = -1;
		int largestFaceArea = -1;
		for( size_t i = 0; i < faces.size(); i++ ) {
			if(faces[i].area() > largestFaceArea) {
				largestFace = i;
				largestFaceArea = faces[i].area();
			}
		}
		if(largestFace >= 0) {
			classificationBoxSet = true;
			double classificationScaleFactor = frameDerivatives->getClassificationScaleFactor();
			classificationBox = faces[largestFace];
			classificationBoxNormalSize = Rect(
				(double)classificationBox.x / classificationScaleFactor,
				(double)classificationBox.y / classificationScaleFactor,
				(double)classificationBox.width / classificationScaleFactor,
				(double)classificationBox.height / classificationScaleFactor);
			//Switch to TRACKING
			trackerState = TRACKING;
			#if (CV_MINOR_VERSION < 3)
			tracker = Tracker::create("KCF");
			#else
			tracker = TrackerKCF::create();
			#endif
			double trackingBoxWidth = (double)classificationBoxNormalSize.width * trackingBoxPercentage;
			double trackingBoxHeight = (double)classificationBoxNormalSize.height * trackingBoxPercentage;
			Rect trackingBox = Rect(
				(double)classificationBoxNormalSize.x + (((double)classificationBoxNormalSize.width - trackingBoxWidth) / 2.0),
				(double)classificationBoxNormalSize.y + (((double)classificationBoxNormalSize.height - trackingBoxHeight) / 2.0),
				trackingBoxWidth,
				trackingBoxHeight);
			tracker->init(frameDerivatives->getCurrentFrame(), trackingBox);
			staleCounter = opticalTrackStaleFramesInterval;
		}
	} else if(trackerState == TRACKING) {
		bool trackSuccess = tracker->update(frameDerivatives->getCurrentFrame(), trackingBox);
		if(!trackSuccess) {
			fprintf(stderr, "FaceTracker WARNING! Track lost. Will keep searching...\n");
			trackingBoxSet = false;
			trackerState = LOST;
			//Attempt to re-process this same frame in LOST mode.
			return this->processCurrentFrame();
		} else {
			trackingBoxSet = true;
			staleCounter--;
			if(staleCounter <= 0) {
				trackerState = STALE;
			}
		}
	}
	return trackerState;
}

void FaceTracker::renderPreviewHUD(void) {
	Mat frame = frameDerivatives->getPreviewFrame();
	if(classificationBoxSet) {
		rectangle(frame, classificationBoxNormalSize, Scalar( 0, 255, 0 ), 1, 0);
	}
	if(trackingBoxSet) {
		rectangle(frame, trackingBox, Scalar( 255, 0, 0 ), 1, 0);
	}
}

TrackerState FaceTracker::getTrackerState(void) {
	return trackerState;
}

}; //namespace YerFace
<commit_msg>fix an issue where stale state would prevent optical tracking from proceeding<commit_after>
#include "FaceTracker.hpp"
#include <exception>
#include <cmath>
#include <stdio.h>

using namespace std;

namespace YerFace {

FaceTracker::FaceTracker(string myClassifierFileName, FrameDerivatives *myFrameDerivatives, float myTrackingBoxPercentage, float myMaxFaceSizePercentage, int myOpticalTrackStaleFramesInterval) {
	classifierFileName = myClassifierFileName;
	frameDerivatives = myFrameDerivatives;
	trackerState = DETECTING;
	classificationBoxSet = false;
	trackingBoxSet = false;

	trackingBoxPercentage = myTrackingBoxPercentage;
	if(trackingBoxPercentage <= 0.0 || trackingBoxPercentage > 1.0) {
		throw invalid_argument("trackingBoxPercentage is out of range.");
	}
	maxFaceSizePercentage = myMaxFaceSizePercentage;
	if(maxFaceSizePercentage <= 0.0 || maxFaceSizePercentage > 1.0) {
		throw invalid_argument("maxFaceSizePercentage is out of range.");
	}
	opticalTrackStaleFramesInterval = myOpticalTrackStaleFramesInterval;
	if(opticalTrackStaleFramesInterval <= 0) {
		throw invalid_argument("opticalTrackStaleFramesInterval is out of range.");
	}
	if(!cascadeClassifier.load(classifierFileName)) {
		throw invalid_argument("Unable to load specified classifier.");
	}
	fprintf(stderr, "FaceTracker object constructed and ready to go!\n");
}

TrackerState FaceTracker::processCurrentFrame(void) {
	if(trackerState == DETECTING || trackerState == LOST || trackerState == STALE) {
		classificationBoxSet = false;
		std::vector<Rect> faces;
		Mat classificationFrame = frameDerivatives->getClassificationFrame();
		double classificationFrameArea = (double)classificationFrame.size().area();
		double maxFaceSize = sqrt(classificationFrameArea * maxFaceSizePercentage);
		cascadeClassifier.detectMultiScale(classificationFrame, faces, 1.1, 3, 0|CASCADE_SCALE_IMAGE, Size(maxFaceSize, maxFaceSize));

		int largestFace = -1;
		int largestFaceArea = -1;
		for( size_t i = 0; i < faces.size(); i++ ) {
			if(faces[i].area() > largestFaceArea) {
				largestFace = i;
				largestFaceArea = faces[i].area();
			}
		}
		if(largestFace >= 0) {
			classificationBoxSet = true;
			double classificationScaleFactor = frameDerivatives->getClassificationScaleFactor();
			classificationBox = faces[largestFace];
			classificationBoxNormalSize = Rect(
				(double)classificationBox.x / classificationScaleFactor,
				(double)classificationBox.y / classificationScaleFactor,
				(double)classificationBox.width / classificationScaleFactor,
				(double)classificationBox.height / classificationScaleFactor);
			//Switch to TRACKING
			trackerState = TRACKING;
			#if (CV_MINOR_VERSION < 3)
			tracker = Tracker::create("KCF");
			#else
			tracker = TrackerKCF::create();
			#endif
			double trackingBoxWidth = (double)classificationBoxNormalSize.width * trackingBoxPercentage;
			double trackingBoxHeight = (double)classificationBoxNormalSize.height * trackingBoxPercentage;
			Rect trackingBox = Rect(
				(double)classificationBoxNormalSize.x + (((double)classificationBoxNormalSize.width - trackingBoxWidth) / 2.0),
				(double)classificationBoxNormalSize.y + (((double)classificationBoxNormalSize.height - trackingBoxHeight) / 2.0),
				trackingBoxWidth,
				trackingBoxHeight);
			tracker->init(frameDerivatives->getCurrentFrame(), trackingBox);
			staleCounter = opticalTrackStaleFramesInterval;
		}
	}
	if(trackerState == TRACKING || trackerState == STALE) {
		bool trackSuccess = tracker->update(frameDerivatives->getCurrentFrame(), trackingBox);
		if(!trackSuccess) {
			fprintf(stderr, "FaceTracker WARNING! Track lost. Will keep searching...\n");
			trackingBoxSet = false;
			trackerState = LOST;
			//Attempt to re-process this same frame in LOST mode.
			return this->processCurrentFrame();
		} else {
			trackingBoxSet = true;
			staleCounter--;
			if(staleCounter <= 0) {
				trackerState = STALE;
			}
		}
	}
	return trackerState;
}

void FaceTracker::renderPreviewHUD(void) {
	Mat frame = frameDerivatives->getPreviewFrame();
	if(classificationBoxSet) {
		rectangle(frame, classificationBoxNormalSize, Scalar( 0, 255, 0 ), 1, 0);
	}
	if(trackingBoxSet) {
		rectangle(frame, trackingBox, Scalar( 255, 0, 0 ), 1, 0);
	}
}

TrackerState FaceTracker::getTrackerState(void) {
	return trackerState;
}

}; //namespace YerFace
<|endoftext|>


<commit_before>// Texture.hh for Fluxbox Window Manager
// Copyright (c) 2002 Henrik Kinnunen (fluxgen@users.sourceforge.net)
//
// from Image.cc for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Texture.cc,v 1.6 2003/08/12 11:44:19 fluxgen Exp $

#include "Texture.hh"

#include <cstring>
#include <cctype>

namespace FbTk {

void Texture::setFromString(const char * const texture_str) {
    if (texture_str == 0)
        return;
    int t_len = strlen(texture_str) + 1;
    char *ts = new char[t_len];
    strcpy(ts, texture_str);

    // to lower
    for (size_t byte_pos = 0; byte_pos < strlen(ts); ++byte_pos)
        ts[byte_pos] = tolower(ts[byte_pos]);

    if (strstr(ts, "parentrelative")) {
        setType(Texture::PARENTRELATIVE);
    } else {
        setType(Texture::NONE);

        if (strstr(ts, "solid"))
            addType(Texture::SOLID);
        else if (strstr(ts, "gradient")) {
            addType(Texture::GRADIENT);
            if (strstr(ts, "crossdiagonal"))
                addType(Texture::CROSSDIAGONAL);
            else if (strstr(ts, "rectangle"))
                addType(Texture::RECTANGLE);
            else if (strstr(ts, "pyramid"))
                addType(Texture::PYRAMID);
            else if (strstr(ts, "pipecross"))
                addType(Texture::PIPECROSS);
            else if (strstr(ts, "elliptic"))
                addType(Texture::ELLIPTIC);
            else if (strstr(ts, "diagonal"))
                addType(Texture::DIAGONAL);
            else if (strstr(ts, "horizontal"))
                addType(Texture::HORIZONTAL);
            else if (strstr(ts, "vertical"))
                addType(Texture::VERTICAL);
            else
                addType(Texture::DIAGONAL);
        } else
            addType(Texture::SOLID);

        if (strstr(ts, "raised"))
            addType(Texture::RAISED);
        else if (strstr(ts, "sunken"))
            addType(Texture::SUNKEN);
        else if (strstr(ts, "flat"))
            addType(Texture::FLAT);
        else
            addType(Texture::RAISED);

        if (! (type() & Texture::FLAT))
            if (strstr(ts, "bevel2"))
                addType(Texture::BEVEL2);
            else
                addType(Texture::BEVEL1);

        if (strstr(ts, "interlaced"))
            addType(Texture::INTERLACED);

        if (strstr(ts, "tiled"))
            addType(Texture::TILED);
    }

    delete [] ts;
}

}; // end namespace FbTk
<commit_msg>added missing invert type<commit_after>// Texture.hh for Fluxbox Window Manager
// Copyright (c) 2002 Henrik Kinnunen (fluxgen@users.sourceforge.net)
//
// from Image.cc for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes@tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: Texture.cc,v 1.7 2004/01/11 20:33:24 fluxgen Exp $

#include "Texture.hh"

#include <cstring>
#include <cctype>

namespace FbTk {

void Texture::setFromString(const char * const texture_str) {
    if (texture_str == 0)
        return;
    int t_len = strlen(texture_str) + 1;
    char *ts = new char[t_len];
    strcpy(ts, texture_str);

    // to lower
    for (size_t byte_pos = 0; byte_pos < strlen(ts); ++byte_pos)
        ts[byte_pos] = tolower(ts[byte_pos]);

    if (strstr(ts, "parentrelative")) {
        setType(Texture::PARENTRELATIVE);
    } else {
        setType(Texture::NONE);

        if (strstr(ts, "solid"))
            addType(Texture::SOLID);
        else if (strstr(ts, "gradient")) {
            addType(Texture::GRADIENT);
            if (strstr(ts, "crossdiagonal"))
                addType(Texture::CROSSDIAGONAL);
            else if (strstr(ts, "rectangle"))
                addType(Texture::RECTANGLE);
            else if (strstr(ts, "pyramid"))
                addType(Texture::PYRAMID);
            else if (strstr(ts, "pipecross"))
                addType(Texture::PIPECROSS);
            else if (strstr(ts, "elliptic"))
                addType(Texture::ELLIPTIC);
            else if (strstr(ts, "diagonal"))
                addType(Texture::DIAGONAL);
            else if (strstr(ts, "horizontal"))
                addType(Texture::HORIZONTAL);
            else if (strstr(ts, "vertical"))
                addType(Texture::VERTICAL);
            else
                addType(Texture::DIAGONAL);
        } else
            addType(Texture::SOLID);

        if (strstr(ts, "raised"))
            addType(Texture::RAISED);
        else if (strstr(ts, "sunken"))
            addType(Texture::SUNKEN);
        else if (strstr(ts, "flat"))
            addType(Texture::FLAT);
        else if (strstr(ts, "invert"))
            addType(Texture::INVERT);
        else
            addType(Texture::RAISED);

        if (! (type() & Texture::FLAT))
            if (strstr(ts, "bevel2"))
                addType(Texture::BEVEL2);
            else
                addType(Texture::BEVEL1);

        if (strstr(ts, "interlaced"))
            addType(Texture::INTERLACED);

        if (strstr(ts, "tiled"))
            addType(Texture::TILED);
    }

    delete [] ts;
}

}; // end namespace FbTk
<|endoftext|>


<commit_before>/*
 * Open Chinese Convert
 *
 * Copyright 2010-2013 BYVoid <byvoid@byvoid.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../dictionary/datrie.h"
#include "../dictionary/text.h"
#include "../dict_group.h"
#include "../encoding.h"
#include "../utils.h"
#include <locale.h>
#include <unistd.h>
#include <darts.hh>

#include <iostream>
#include <vector>
#include <string>

using std::vector;
using std::string;

#ifndef VERSION
#define VERSION ""
#endif

#define DATRIE_SIZE 1000000
#define DATRIE_WORD_MAX_COUNT 500000
#define BUFFER_SIZE 1024

struct Value {
  string value;
  size_t cursor;
  Value(string value_, size_t cursor_) : value(value_), cursor(cursor_) {
  }
};

struct Entry {
  string key;
  vector<size_t> valueIndexes;
};

vector<Entry> lexicon;
vector<Value> values;
Darts::DoubleArray dict;

size_t lexicon_index_length, lexicon_cursor_end;

void make() {
  vector<const char*> keys;
  vector<int> valueIndexes;
  keys.reserve(lexicon.size());
  for (size_t i = 0; i < lexicon.size(); i++) {
    keys.push_back(lexicon[i].key.c_str());
  }
  dict.build(lexicon.size(), &keys[0]);
}

int cmp(const void* a, const void* b) {
  return ucs4cmp(((const TextEntry*)a)->key, ((const TextEntry*)b)->key);
}

void init(const char* filename) {
  DictGroup* DictGroup = dict_group_new(NULL);
  if (dict_group_load(DictGroup, filename,
                            OPENCC_DICTIONARY_TYPE_TEXT) == -1) {
    dictionary_perror("Dictionary loading error");
    fprintf(stderr, _("\n"));
    exit(1);
  }
  Dict* dict_abs = dict_group_get_dict(DictGroup, 0);
  if (dict_abs == (Dict*)-1) {
    dictionary_perror("Dictionary loading error");
    fprintf(stderr, _("\n"));
    exit(1);
  }
  static TextEntry tlexicon[DATRIE_WORD_MAX_COUNT];
  /* TODO add datrie support */
  Dict* dictionary = dict_abs->dict;
  size_t lexicon_count = dict_text_get_lexicon(dictionary, tlexicon);
  qsort(tlexicon, lexicon_count, sizeof(tlexicon[0]), cmp);
  size_t lexicon_cursor = 0;
  lexicon.resize(lexicon_count);
  for (size_t i = 0; i < lexicon_count; i++) {
    char* utf8_temp = ucs4_to_utf8(tlexicon[i].key, (size_t)-1);
    lexicon[i].key = utf8_temp;
    free(utf8_temp);
    size_t value_count;
    for (value_count = 0; tlexicon[i].value[value_count] != NULL; value_count++) {}
    for (size_t j = 0; j < value_count; j++) {
      lexicon[i].valueIndexes.push_back(values.size());
      char* utf8_temp = ucs4_to_utf8(tlexicon[i].value[j], (size_t)-1);
      values.push_back(Value(utf8_temp, lexicon_cursor));
      free(utf8_temp);
      lexicon_cursor += ucs4len(tlexicon[i].value[j]) + 1;
    }
    lexicon_index_length += value_count + 1;
  }
  lexicon_cursor_end = lexicon_cursor;
}

void output(const char* file_name) {
  dict.save(file_name);
  size_t dartsSize = dict.total_size();

  /*
  FILE* fp = fopen(file_name, "wb");
  if (!fp) {
    fprintf(stderr, _("Can not write file: %s\n"), file_name);
    exit(1);
  }
  uint32_t i, item_count;
  for (i = DATRIE_SIZE - 1; i > 0; i--) {
    if (dat[i].parent != DATRIE_UNUSED) {
      break;
    }
  }
  item_count = i + 1;
  fwrite("OPENCCDATRIE", sizeof(char), strlen("OPENCCDATRIE"), fp);
  // 詞彙表長度
  fwrite(&lexicon_cursor_end, sizeof(uint32_t), 1, fp);
  for (i = 0; i < lexicon_count; i++) {
    size_t j;
    for (j = 0; j < lexicon[i].value_count; j++) {
      fwrite(lexicon[i].value[j].pointer, sizeof(ucs4_t),
             ucs4len(lexicon[i].value[j].pointer) + 1, fp);
    }
  }
  // 詞彙索引表長度
  fwrite(&lexicon_index_length, sizeof(uint32_t), 1, fp);
  for (i = 0; i < lexicon_count; i++) {
    size_t j;
    for (j = 0; j < lexicon[i].value_count; j++) {
      fwrite(&lexicon[i].value[j].cursor, sizeof(uint32_t), 1, fp);
    }
    uint32_t dem = (uint32_t)-1;
    fwrite(&dem, sizeof(uint32_t), 1, fp);             //分隔符
  }
  fwrite(&lexicon_count, sizeof(uint32_t), 1, fp);
  fwrite(&item_count, sizeof(uint32_t), 1, fp);
  fwrite(dat, sizeof(dat[0]), item_count, fp);
  fclose(fp);
  */
}

#ifdef DEBUG_WRITE_TEXT
void write_text_file() {
  FILE* fp;
  int i;
  fp = fopen("datrie.txt", "w");
  fprintf(fp, "%d\n", lexicon_count);
  for (i = 0; i < lexicon_count; i++) {
    char* buff = ucs4_to_utf8(lexicon[i].value, (size_t)-1);
    fprintf(fp, "%s\n", buff);
    free(buff);
  }
  for (i = 0; i < DATRIE_SIZE; i++) {
    if (dat[i].parent != DATRIE_UNUSED) {
      fprintf(fp, "%d %d %d %d\n", i, dat[i].base, dat[i].parent, dat[i].word);
    }
  }
  fclose(fp);
}

#endif /* ifdef DEBUG_WRITE_TEXT */

void show_version() {
  printf(_("\nOpen Chinese Convert (OpenCC) Dictionary Tool\nVersion %s\n\n"),
         VERSION);
}

void show_usage() {
  show_version();
  printf(_("Usage:\n"));
  printf(_("  opencc_dict -i input_file -o output_file\n\n"));
  printf(_("    -i input_file\n"));
  printf(_("      Read data from input_file.\n"));
  printf(_("    -o output_file\n"));
  printf(_("      Write converted data to output_file.\n"));
  printf(_("\n"));
  printf(_("\n"));
}

int main(int argc, char** argv) {
  static int oc;
  static char input_file[BUFFER_SIZE], output_file[BUFFER_SIZE];
  int input_file_specified = 0, output_file_specified = 0;

#ifdef ENABLE_GETTEXT
  setlocale(LC_ALL, "");
  bindtextdomain(PACKAGE_NAME, LOCALEDIR);
#endif /* ifdef ENABLE_GETTEXT */
  while ((oc = getopt(argc, argv, "vh-:i:o:")) != -1) {
    switch (oc) {
    case 'v':
      show_version();
      return 0;
    case 'h':
    case '?':
      show_usage();
      return 0;
    case '-':
      if (strcmp(optarg, "version") == 0) {
        show_version();
      } else {
        show_usage();
      }
      return 0;
    case 'i':
      strcpy(input_file, optarg);
      input_file_specified = 1;
      break;
    case 'o':
      strcpy(output_file, optarg);
      output_file_specified = 1;
      break;
    }
  }
  if (!input_file_specified) {
    fprintf(stderr, _("Please specify input file using -i.\n"));
    show_usage();
    return 1;
  }
  if (!output_file_specified) {
    fprintf(stderr, _("Please specify output file using -o.\n"));
    show_usage();
    return 1;
  }
  init(input_file);
  make();
  output(output_file);
#ifdef DEBUG_WRITE_TEXT
  write_text_file();
#endif /* ifdef DEBUG_WRITE_TEXT */
  return 0;
}
<commit_msg>Serialization opencc dictionary with darts<commit_after>/*
 * Open Chinese Convert
 *
 * Copyright 2010-2013 BYVoid <byvoid@byvoid.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "../dictionary/datrie.h"
#include "../dictionary/text.h"
#include "../dict_group.h"
#include "../encoding.h"
#include "../utils.h"
#include <locale.h>
#include <unistd.h>
#include <darts.hh>

#include <iostream>
#include <vector>
#include <string>

using std::vector;
using std::string;

#ifndef VERSION
#define VERSION ""
#endif

#define DATRIE_SIZE 1000000
#define DATRIE_WORD_MAX_COUNT 500000
#define BUFFER_SIZE 1024

const char* OCDHEADER = "OPENCCDICTIONARY1";

struct Value {
  string value;
  size_t cursor;
  Value(string value_, size_t cursor_) : value(value_), cursor(cursor_) {
  }
};

struct Entry {
  string key;
  vector<size_t> valueIndexes;
};

vector<Entry> lexicon;
vector<Value> values;
Darts::DoubleArray dict;

void make() {
  vector<const char*> keys;
  vector<int> valueIndexes;
  keys.reserve(lexicon.size());
  for (size_t i = 0; i < lexicon.size(); i++) {
    keys.push_back(lexicon[i].key.c_str());
  }
  dict.build(lexicon.size(), &keys[0]);
}

int cmp(const void* a, const void* b) {
  return ucs4cmp(((const TextEntry*)a)->key, ((const TextEntry*)b)->key);
}

void init(const char* filename) {
  DictGroup* DictGroup = dict_group_new(NULL);
  if (dict_group_load(DictGroup, filename,
                            OPENCC_DICTIONARY_TYPE_TEXT) == -1) {
    dictionary_perror("Dictionary loading error");
    fprintf(stderr, _("\n"));
    exit(1);
  }
  Dict* dict_abs = dict_group_get_dict(DictGroup, 0);
  if (dict_abs == (Dict*)-1) {
    dictionary_perror("Dictionary loading error");
    fprintf(stderr, _("\n"));
    exit(1);
  }
  static TextEntry tlexicon[DATRIE_WORD_MAX_COUNT];
  /* TODO add datrie support */
  Dict* dictionary = dict_abs->dict;
  size_t lexicon_count = dict_text_get_lexicon(dictionary, tlexicon);
  qsort(tlexicon, lexicon_count, sizeof(tlexicon[0]), cmp);
  size_t lexicon_cursor = 0;
  lexicon.resize(lexicon_count);
  for (size_t i = 0; i < lexicon_count; i++) {
    char* utf8_temp = ucs4_to_utf8(tlexicon[i].key, (size_t)-1);
    lexicon[i].key = utf8_temp;
    free(utf8_temp);
    size_t value_count;
    for (value_count = 0; tlexicon[i].value[value_count] != NULL; value_count++) {}
    for (size_t j = 0; j < value_count; j++) {
      lexicon[i].valueIndexes.push_back(values.size());
      char* utf8_temp = ucs4_to_utf8(tlexicon[i].value[j], (size_t)-1);
      values.push_back(Value(utf8_temp, lexicon_cursor));
      lexicon_cursor += strlen(utf8_temp);
      free(utf8_temp);
    }
  }
}

void output(const char* file_name) {
  FILE* fp = fopen(file_name, "wb");
  if (!fp) {
    fprintf(stderr, _("Can not write file: %s\n"), file_name);
    exit(1);
  }
  /*
   Binary Structure
   [OCDHEADER]
   [number of keys]
     size_t
   [number of values]
     size_t
   [bytes of values]
     size_t
   [bytes of darts]
     size_t
   [key indexes]
     size_t(index of first value) * [number of keys]
   [value indexes]
     size_t(index of first char) * [number of values]
   [value data]
     char * [bytes of values]
   [darts]
     char * [bytes of darts]
   */
  size_t numKeys = lexicon.size();
  size_t numValues = values.size();
  size_t dartsSize = dict.total_size();

  fwrite(OCDHEADER, sizeof(char), strlen(OCDHEADER), fp);
  fwrite(&numKeys, sizeof(size_t), 1, fp);
  fwrite(&numValues, sizeof(size_t), 1, fp);
  fwrite(&dartsSize, sizeof(size_t), 1, fp);

  // key indexes
  for (size_t i = 0; i < numKeys; i++) {
    size_t index = lexicon[i].valueIndexes[0];
    fwrite(&index, sizeof(size_t), 1, fp);
  }

  // value indexes
  for (size_t i = 0; i < numValues; i++) {
    size_t index = values[i].cursor;
    fwrite(&index, sizeof(size_t), 1, fp);
  }

  // value data
  for (size_t i = 0; i < numValues; i++) {
    const char* value = values[i].value.c_str();
    fwrite(value, sizeof(char), strlen(value), fp);
  }

  // darts
  fwrite(dict.array(), sizeof(char), dartsSize, fp);

  fclose(fp);
}

#ifdef DEBUG_WRITE_TEXT
void write_text_file() {
  FILE* fp;
  int i;
  fp = fopen("datrie.txt", "w");
  fprintf(fp, "%d\n", lexicon_count);
  for (i = 0; i < lexicon_count; i++) {
    char* buff = ucs4_to_utf8(lexicon[i].value, (size_t)-1);
    fprintf(fp, "%s\n", buff);
    free(buff);
  }
  for (i = 0; i < DATRIE_SIZE; i++) {
    if (dat[i].parent != DATRIE_UNUSED) {
      fprintf(fp, "%d %d %d %d\n", i, dat[i].base, dat[i].parent, dat[i].word);
    }
  }
  fclose(fp);
}

#endif /* ifdef DEBUG_WRITE_TEXT */

void show_version() {
  printf(_("\nOpen Chinese Convert (OpenCC) Dictionary Tool\nVersion %s\n\n"),
         VERSION);
}

void show_usage() {
  show_version();
  printf(_("Usage:\n"));
  printf(_("  opencc_dict -i input_file -o output_file\n\n"));
  printf(_("    -i input_file\n"));
  printf(_("      Read data from input_file.\n"));
  printf(_("    -o output_file\n"));
  printf(_("      Write converted data to output_file.\n"));
  printf(_("\n"));
  printf(_("\n"));
}

int main(int argc, char** argv) {
  static int oc;
  static char input_file[BUFFER_SIZE], output_file[BUFFER_SIZE];
  int input_file_specified = 0, output_file_specified = 0;

#ifdef ENABLE_GETTEXT
  setlocale(LC_ALL, "");
  bindtextdomain(PACKAGE_NAME, LOCALEDIR);
#endif /* ifdef ENABLE_GETTEXT */
  while ((oc = getopt(argc, argv, "vh-:i:o:")) != -1) {
    switch (oc) {
    case 'v':
      show_version();
      return 0;
    case 'h':
    case '?':
      show_usage();
      return 0;
    case '-':
      if (strcmp(optarg, "version") == 0) {
        show_version();
      } else {
        show_usage();
      }
      return 0;
    case 'i':
      strcpy(input_file, optarg);
      input_file_specified = 1;
      break;
    case 'o':
      strcpy(output_file, optarg);
      output_file_specified = 1;
      break;
    }
  }
  if (!input_file_specified) {
    fprintf(stderr, _("Please specify input file using -i.\n"));
    show_usage();
    return 1;
  }
  if (!output_file_specified) {
    fprintf(stderr, _("Please specify output file using -o.\n"));
    show_usage();
    return 1;
  }
  init(input_file);
  make();
  output(output_file);
#ifdef DEBUG_WRITE_TEXT
  write_text_file();
#endif /* ifdef DEBUG_WRITE_TEXT */
  return 0;
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#ifndef PCL_FEATURES_IMPL_FEATURE_H_
#define PCL_FEATURES_IMPL_FEATURE_H_

#include <pcl/search/pcl_search.h>

//////////////////////////////////////////////////////////////////////////////////////////////
inline void
pcl::solvePlaneParameters (const Eigen::Matrix3f &covariance_matrix,
                           const Eigen::Vector4f &point,
                           Eigen::Vector4f &plane_parameters, float &curvature)
{
  solvePlaneParameters (covariance_matrix, plane_parameters [0], plane_parameters [1], plane_parameters [2], curvature);

  plane_parameters[3] = 0;
  // Hessian form (D = nc . p_plane (centroid here) + p)
  plane_parameters[3] = -1 * plane_parameters.dot (point);
}

//////////////////////////////////////////////////////////////////////////////////////////////
inline void
pcl::solvePlaneParameters (const Eigen::Matrix3f &covariance_matrix,
                           float &nx, float &ny, float &nz, float &curvature)
{
  // Avoid getting hung on Eigen's optimizers
//  for (int i = 0; i < 9; ++i)
//    if (!pcl_isfinite (covariance_matrix.coeff (i)))
//    {
//      //PCL_WARN ("[pcl::solvePlaneParameteres] Covariance matrix has NaN/Inf values!\n");
//      nx = ny = nz = curvature = std::numeric_limits<float>::quiet_NaN ();
//      return;
//    }
  // Extract the smallest eigenvalue and its eigenvector
  EIGEN_ALIGN16 Eigen::Vector3f::Scalar eigen_value;
  EIGEN_ALIGN16 Eigen::Vector3f eigen_vector;
  pcl::eigen33 (covariance_matrix, eigen_value, eigen_vector);

  nx = eigen_vector [0];
  ny = eigen_vector [1];
  nz = eigen_vector [2];

  // Compute the curvature surface change
  float eig_sum = covariance_matrix.coeff (0) + covariance_matrix.coeff (4) + covariance_matrix.coeff (8);
  if (eig_sum != 0)
    curvature = fabsf (eigen_value / eig_sum);
  else
    curvature = 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> bool
pcl::Feature<PointInT, PointOutT>::initCompute ()
{
  if (!PCLBase<PointInT>::initCompute ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
    return (false);
  }

  // If the dataset is empty, just return
  if (input_->points.empty ())
  {
    PCL_ERROR ("[pcl::%s::compute] input_ is empty!\n", getClassName ().c_str ());
    // Cleanup
    deinitCompute ();
    return (false);
  }

  // If no search surface has been defined, use the input dataset as the search surface itself
  if (!surface_)
  {
    fake_surface_ = true;
    surface_ = input_;
  }

  // Check if a space search locator was given
  if (!tree_)
  {
    if (surface_->isOrganized () && input_->isOrganized ())
      tree_.reset (new pcl::search::OrganizedNeighbor<PointInT> ());
    else
      tree_.reset (new pcl::search::KdTree<PointInT> (false));
  }
  // Send the surface dataset to the spatial locator
  tree_->setInputCloud (surface_);

  // Do a fast check to see if the search parameters are well defined
  if (search_radius_ != 0.0)
  {
    if (k_ != 0)
    {
      PCL_ERROR ("[pcl::%s::compute] ", getClassName ().c_str ());
      PCL_ERROR ("Both radius (%f) and K (%d) defined! ", search_radius_, k_);
      PCL_ERROR ("Set one of them to zero first and then re-run compute ().\n");
      // Cleanup
      deinitCompute ();
      return (false);
    }
    else // Use the radiusSearch () function
    {
      search_parameter_ = search_radius_;
      if (surface_ == input_) // if the two surfaces are the same
      {
        // Declare the search locator definition
        int (KdTree::*radiusSearch)(int index, double radius, std::vector<int> &k_indices,
                                    std::vector<float> &k_distances, unsigned int max_nn) const = &KdTree::radiusSearch;
        search_method_ = boost::bind (radiusSearch, boost::ref (tree_), _1, _2, _3, _4, 0);
      }

      // Declare the search locator definition
      int (KdTree::*radiusSearchSurface)(const PointCloudIn &cloud, int index, double radius,
                                         std::vector<int> &k_indices, std::vector<float> &k_distances,
                                         unsigned int max_nn) const = &pcl::search::Search<PointInT>::radiusSearch;
      search_method_surface_ = boost::bind (radiusSearchSurface, boost::ref (tree_), _1, _2, _3, _4, _5, 0);
    }
  }
  else
  {
    if (k_ != 0) // Use the nearestKSearch () function
    {
      search_parameter_ = k_;
      if (surface_ == input_) // if the two surfaces are the same
      {
        // Declare the search locator definition
        int (KdTree::*nearestKSearch)(int index, int k, std::vector<int> &k_indices,
                                      std::vector<float> &k_distances) const = &KdTree::nearestKSearch;
        search_method_ = boost::bind (nearestKSearch, boost::ref (tree_), _1, _2, _3, _4);
      }
      // Declare the search locator definition
      int (KdTree::*nearestKSearchSurface)(const PointCloudIn &cloud, int index, int k, std::vector<int> &k_indices,
                                           std::vector<float> &k_distances) const = &KdTree::nearestKSearch;
      search_method_surface_ = boost::bind (nearestKSearchSurface, boost::ref (tree_), _1, _2, _3, _4, _5);
    }
    else
    {
      PCL_ERROR ("[pcl::%s::compute] Neither radius nor K defined! ", getClassName ().c_str ());
      PCL_ERROR ("Set one of them to a positive number first and then re-run compute ().\n");
      // Cleanup
      deinitCompute ();
      return (false);
    }
  }
  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> bool
pcl::Feature<PointInT, PointOutT>::deinitCompute ()
{
  // Reset the surface
  if (fake_surface_)
  {
    surface_.reset ();
    fake_surface_ = false;
  }
  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::Feature<PointInT, PointOutT>::compute (PointCloudOut &output)
{
  if (!initCompute ())
  {
    output.width = output.height = 0;
    output.points.clear ();
    return;
  }

  // Copy the header
  output.header = input_->header;

  // Resize the output dataset
  if (output.points.size () != indices_->size ())
    output.points.resize (indices_->size ());
  // Check if the output will be computed for all points or only a subset
  if (indices_->size () != input_->points.size ())
  {
    output.width = static_cast<int> (indices_->size ());
    output.height = 1;
  }
  else
  {
    output.width = input_->width;
    output.height = input_->height;
  }
  output.is_dense = input_->is_dense;

  // Perform the actual feature computation
  computeFeature (output);

  deinitCompute ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::Feature<PointInT, PointOutT>::computeEigen (pcl::PointCloud<Eigen::MatrixXf> &output)
{
  if (!initCompute ())
  {
    output.width = output.height = 0;
    output.points.resize (0, 0);
    return;
  }

  // Copy the properties
//#ifndef USE_ROS
//  output.properties.acquisition_time = input_->header.stamp;
//#endif
  output.properties.sensor_origin = input_->sensor_origin_;
  output.properties.sensor_orientation = input_->sensor_orientation_;

  // Check if the output will be computed for all points or only a subset
  if (indices_->size () != input_->points.size ())
  {
    output.width = static_cast<int> (indices_->size ());
    output.height = 1;
  }
  else
  {
    output.width = input_->width;
    output.height = input_->height;
  }

  output.is_dense = input_->is_dense;

  // Perform the actual feature computation
  computeFeatureEigen (output);

  deinitCompute ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointNT, typename PointOutT> bool
pcl::FeatureFromNormals<PointInT, PointNT, PointOutT>::initCompute ()
{
  if (!Feature<PointInT, PointOutT>::initCompute ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
    return (false);
  }

  // Check if input normals are set
  if (!normals_)
  {
    PCL_ERROR ("[pcl::%s::initCompute] No input dataset containing normals was given!\n", getClassName ().c_str ());
    Feature<PointInT, PointOutT>::deinitCompute ();
    return (false);
  }

  // Check if the size of normals is the same as the size of the surface
  if (normals_->points.size () != surface_->points.size ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] ", getClassName ().c_str ());
    PCL_ERROR ("The number of points in the input dataset (%u) differs from ", surface_->points.size ());
    PCL_ERROR ("the number of points in the dataset containing the normals (%u)!\n", normals_->points.size ());
    Feature<PointInT, PointOutT>::deinitCompute ();
    return (false);
  }

  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointLT, typename PointOutT> bool
pcl::FeatureFromLabels<PointInT, PointLT, PointOutT>::initCompute ()
{
  if (!Feature<PointInT, PointOutT>::initCompute ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
    return (false);
  }

  // Check if input normals are set
  if (!labels_)
  {
    PCL_ERROR ("[pcl::%s::initCompute] No input dataset containing labels was given!\n", getClassName ().c_str ());
    Feature<PointInT, PointOutT>::deinitCompute ();
    return (false);
  }

  // Check if the size of normals is the same as the size of the surface
  if (labels_->points.size () != surface_->points.size ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] The number of points in the input dataset differs from the number of points in the dataset containing the labels!\n", getClassName ().c_str ());
    Feature<PointInT, PointOutT>::deinitCompute ();
    return (false);
  }

  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointRFT> bool
pcl::FeatureWithLocalReferenceFrames<PointInT, PointRFT>::initLocalReferenceFrames (const PointCloudInConstPtr& input,
                                                                                const LRFEstimationPtr& lrf_estimation)
{
  // Check if input frames are set
  if (!frames_)
  {
    if (!lrf_estimation)
    {
      PCL_ERROR ("[initLocalReferenceFrames] No input dataset containing reference frames was given!\n");
      return (false);
    } else
    {
      PCL_WARN ("[initLocalReferenceFrames] No input dataset containing reference frames was given! Default computation with %s\n", lrf_estimation->getClassName ());
      lrf_estimation->compute (*frames_);
    }
  }

  // Check if the size of frames is the same as the size of the input cloud
  if (frames_->points.size () != input->points.size ())
  {
    if (!lrf_estimation)
    {
      PCL_ERROR ("[initLocalReferenceFrames] The number of points in the input dataset differs from the number of points in the dataset containing the reference frames!\n");
      return (false);
    } else
    {
      PCL_WARN ("[initLocalReferenceFrames] The number of points in the input dataset differs from the number of points in the dataset containing the reference frames! Default computation with %s\n", lrf_estimation->getClassName ());
      lrf_estimation->compute (*frames_);
    }
  }

  return (true);
}

#endif  //#ifndef PCL_FEATURES_IMPL_FEATURE_H_

<commit_msg>FeatureWithLocalReferenceFrames: Minor bugs fixed<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2010-2011, Willow Garage, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#ifndef PCL_FEATURES_IMPL_FEATURE_H_
#define PCL_FEATURES_IMPL_FEATURE_H_

#include <pcl/search/pcl_search.h>

//////////////////////////////////////////////////////////////////////////////////////////////
inline void
pcl::solvePlaneParameters (const Eigen::Matrix3f &covariance_matrix,
                           const Eigen::Vector4f &point,
                           Eigen::Vector4f &plane_parameters, float &curvature)
{
  solvePlaneParameters (covariance_matrix, plane_parameters [0], plane_parameters [1], plane_parameters [2], curvature);

  plane_parameters[3] = 0;
  // Hessian form (D = nc . p_plane (centroid here) + p)
  plane_parameters[3] = -1 * plane_parameters.dot (point);
}

//////////////////////////////////////////////////////////////////////////////////////////////
inline void
pcl::solvePlaneParameters (const Eigen::Matrix3f &covariance_matrix,
                           float &nx, float &ny, float &nz, float &curvature)
{
  // Avoid getting hung on Eigen's optimizers
//  for (int i = 0; i < 9; ++i)
//    if (!pcl_isfinite (covariance_matrix.coeff (i)))
//    {
//      //PCL_WARN ("[pcl::solvePlaneParameteres] Covariance matrix has NaN/Inf values!\n");
//      nx = ny = nz = curvature = std::numeric_limits<float>::quiet_NaN ();
//      return;
//    }
  // Extract the smallest eigenvalue and its eigenvector
  EIGEN_ALIGN16 Eigen::Vector3f::Scalar eigen_value;
  EIGEN_ALIGN16 Eigen::Vector3f eigen_vector;
  pcl::eigen33 (covariance_matrix, eigen_value, eigen_vector);

  nx = eigen_vector [0];
  ny = eigen_vector [1];
  nz = eigen_vector [2];

  // Compute the curvature surface change
  float eig_sum = covariance_matrix.coeff (0) + covariance_matrix.coeff (4) + covariance_matrix.coeff (8);
  if (eig_sum != 0)
    curvature = fabsf (eigen_value / eig_sum);
  else
    curvature = 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> bool
pcl::Feature<PointInT, PointOutT>::initCompute ()
{
  if (!PCLBase<PointInT>::initCompute ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
    return (false);
  }

  // If the dataset is empty, just return
  if (input_->points.empty ())
  {
    PCL_ERROR ("[pcl::%s::compute] input_ is empty!\n", getClassName ().c_str ());
    // Cleanup
    deinitCompute ();
    return (false);
  }

  // If no search surface has been defined, use the input dataset as the search surface itself
  if (!surface_)
  {
    fake_surface_ = true;
    surface_ = input_;
  }

  // Check if a space search locator was given
  if (!tree_)
  {
    if (surface_->isOrganized () && input_->isOrganized ())
      tree_.reset (new pcl::search::OrganizedNeighbor<PointInT> ());
    else
      tree_.reset (new pcl::search::KdTree<PointInT> (false));
  }
  // Send the surface dataset to the spatial locator
  tree_->setInputCloud (surface_);

  // Do a fast check to see if the search parameters are well defined
  if (search_radius_ != 0.0)
  {
    if (k_ != 0)
    {
      PCL_ERROR ("[pcl::%s::compute] ", getClassName ().c_str ());
      PCL_ERROR ("Both radius (%f) and K (%d) defined! ", search_radius_, k_);
      PCL_ERROR ("Set one of them to zero first and then re-run compute ().\n");
      // Cleanup
      deinitCompute ();
      return (false);
    }
    else // Use the radiusSearch () function
    {
      search_parameter_ = search_radius_;
      if (surface_ == input_) // if the two surfaces are the same
      {
        // Declare the search locator definition
        int (KdTree::*radiusSearch)(int index, double radius, std::vector<int> &k_indices,
                                    std::vector<float> &k_distances, unsigned int max_nn) const = &KdTree::radiusSearch;
        search_method_ = boost::bind (radiusSearch, boost::ref (tree_), _1, _2, _3, _4, 0);
      }

      // Declare the search locator definition
      int (KdTree::*radiusSearchSurface)(const PointCloudIn &cloud, int index, double radius,
                                         std::vector<int> &k_indices, std::vector<float> &k_distances,
                                         unsigned int max_nn) const = &pcl::search::Search<PointInT>::radiusSearch;
      search_method_surface_ = boost::bind (radiusSearchSurface, boost::ref (tree_), _1, _2, _3, _4, _5, 0);
    }
  }
  else
  {
    if (k_ != 0) // Use the nearestKSearch () function
    {
      search_parameter_ = k_;
      if (surface_ == input_) // if the two surfaces are the same
      {
        // Declare the search locator definition
        int (KdTree::*nearestKSearch)(int index, int k, std::vector<int> &k_indices,
                                      std::vector<float> &k_distances) const = &KdTree::nearestKSearch;
        search_method_ = boost::bind (nearestKSearch, boost::ref (tree_), _1, _2, _3, _4);
      }
      // Declare the search locator definition
      int (KdTree::*nearestKSearchSurface)(const PointCloudIn &cloud, int index, int k, std::vector<int> &k_indices,
                                           std::vector<float> &k_distances) const = &KdTree::nearestKSearch;
      search_method_surface_ = boost::bind (nearestKSearchSurface, boost::ref (tree_), _1, _2, _3, _4, _5);
    }
    else
    {
      PCL_ERROR ("[pcl::%s::compute] Neither radius nor K defined! ", getClassName ().c_str ());
      PCL_ERROR ("Set one of them to a positive number first and then re-run compute ().\n");
      // Cleanup
      deinitCompute ();
      return (false);
    }
  }
  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> bool
pcl::Feature<PointInT, PointOutT>::deinitCompute ()
{
  // Reset the surface
  if (fake_surface_)
  {
    surface_.reset ();
    fake_surface_ = false;
  }
  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::Feature<PointInT, PointOutT>::compute (PointCloudOut &output)
{
  if (!initCompute ())
  {
    output.width = output.height = 0;
    output.points.clear ();
    return;
  }

  // Copy the header
  output.header = input_->header;

  // Resize the output dataset
  if (output.points.size () != indices_->size ())
    output.points.resize (indices_->size ());
  // Check if the output will be computed for all points or only a subset
  if (indices_->size () != input_->points.size ())
  {
    output.width = static_cast<int> (indices_->size ());
    output.height = 1;
  }
  else
  {
    output.width = input_->width;
    output.height = input_->height;
  }
  output.is_dense = input_->is_dense;

  // Perform the actual feature computation
  computeFeature (output);

  deinitCompute ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointOutT> void
pcl::Feature<PointInT, PointOutT>::computeEigen (pcl::PointCloud<Eigen::MatrixXf> &output)
{
  if (!initCompute ())
  {
    output.width = output.height = 0;
    output.points.resize (0, 0);
    return;
  }

  // Copy the properties
//#ifndef USE_ROS
//  output.properties.acquisition_time = input_->header.stamp;
//#endif
  output.properties.sensor_origin = input_->sensor_origin_;
  output.properties.sensor_orientation = input_->sensor_orientation_;

  // Check if the output will be computed for all points or only a subset
  if (indices_->size () != input_->points.size ())
  {
    output.width = static_cast<int> (indices_->size ());
    output.height = 1;
  }
  else
  {
    output.width = input_->width;
    output.height = input_->height;
  }

  output.is_dense = input_->is_dense;

  // Perform the actual feature computation
  computeFeatureEigen (output);

  deinitCompute ();
}

//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointNT, typename PointOutT> bool
pcl::FeatureFromNormals<PointInT, PointNT, PointOutT>::initCompute ()
{
  if (!Feature<PointInT, PointOutT>::initCompute ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
    return (false);
  }

  // Check if input normals are set
  if (!normals_)
  {
    PCL_ERROR ("[pcl::%s::initCompute] No input dataset containing normals was given!\n", getClassName ().c_str ());
    Feature<PointInT, PointOutT>::deinitCompute ();
    return (false);
  }

  // Check if the size of normals is the same as the size of the surface
  if (normals_->points.size () != surface_->points.size ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] ", getClassName ().c_str ());
    PCL_ERROR ("The number of points in the input dataset (%u) differs from ", surface_->points.size ());
    PCL_ERROR ("the number of points in the dataset containing the normals (%u)!\n", normals_->points.size ());
    Feature<PointInT, PointOutT>::deinitCompute ();
    return (false);
  }

  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointLT, typename PointOutT> bool
pcl::FeatureFromLabels<PointInT, PointLT, PointOutT>::initCompute ()
{
  if (!Feature<PointInT, PointOutT>::initCompute ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
    return (false);
  }

  // Check if input normals are set
  if (!labels_)
  {
    PCL_ERROR ("[pcl::%s::initCompute] No input dataset containing labels was given!\n", getClassName ().c_str ());
    Feature<PointInT, PointOutT>::deinitCompute ();
    return (false);
  }

  // Check if the size of normals is the same as the size of the surface
  if (labels_->points.size () != surface_->points.size ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] The number of points in the input dataset differs from the number of points in the dataset containing the labels!\n", getClassName ().c_str ());
    Feature<PointInT, PointOutT>::deinitCompute ();
    return (false);
  }

  return (true);
}

//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
template <typename PointInT, typename PointRFT> bool
pcl::FeatureWithLocalReferenceFrames<PointInT, PointRFT>::initLocalReferenceFrames (const PointCloudInConstPtr& input,
                                                                                const LRFEstimationPtr& lrf_estimation)
{
  // Check if input frames are set
  if (!frames_)
  {
    if (!lrf_estimation)
    {
      PCL_ERROR ("[initLocalReferenceFrames] No input dataset containing reference frames was given!\n");
      return (false);
    } else
    {
      PCL_WARN ("[initLocalReferenceFrames] No input dataset containing reference frames was given! Proceed using default\n");
      PointCloudLRFPtr default_frames (new PointCloudLRF());
      lrf_estimation->compute (*default_frames);
      frames_ = default_frames;
    }
  }

  // Check if the size of frames is the same as the size of the input cloud
  if (frames_->points.size () != input->points.size ())
  {
    if (!lrf_estimation)
    {
      PCL_ERROR ("[initLocalReferenceFrames] The number of points in the input dataset differs from the number of points in the dataset containing the reference frames!\n");
      return (false);
    } else
    {
      PCL_WARN ("[initLocalReferenceFrames] The number of points in the input dataset differs from the number of points in the dataset containing the reference frames! Proceed using default\n");
      PointCloudLRFPtr default_frames (new PointCloudLRF());
      lrf_estimation->compute (*default_frames);
      frames_ = default_frames;
    }
  }

  return (true);
}

#endif  //#ifndef PCL_FEATURES_IMPL_FEATURE_H_

<|endoftext|>


<commit_before><commit_msg>#65293# don't use namespace svxform her for svx_light<commit_after><|endoftext|>