14 #ifndef ALICEVISION_EIGEN_REQUIRE_ALIGNMENT
15 #ifndef EIGEN_MAX_ALIGN_BYTES
16 #error "EIGEN_MAX_ALIGN_BYTES is not defined"
17 #elif EIGEN_MAX_ALIGN_BYTES != 0
18 #error "EIGEN_MAX_ALIGN_BYTES is defined but not 0"
21 #ifndef EIGEN_MAX_STATIC_ALIGN_BYTES
22 #error "EIGEN_MAX_STATIC_ALIGN_BYTES is not defined"
23 #elif EIGEN_MAX_STATIC_ALIGN_BYTES != 0
24 #error "EIGEN_MAX_STATIC_ALIGN_BYTES is defined but not 0"
34 #include <Eigen/Eigenvalues>
35 #include <Eigen/Geometry>
38 #include <Eigen/SparseCore>
40 #include <Eigen/StdVector>
41 #include <boost/math/constants/constants.hpp>
63 #if __x86_64__ || __ppc64__ || _LP64
72 using EigenDoubleTraits = Eigen::NumTraits<double>;
74 using Vec3 = Eigen::Vector3d;
75 using Vec3i = Eigen::Vector3i;
76 using Vec3f = Eigen::Vector3f;
78 using Vec2i = Eigen::Vector2i;
79 using Vec2f = Eigen::Vector2f;
81 using Vec9 = Eigen::Matrix<double, 9, 1>;
83 using Quaternion = Eigen::Quaternion<double>;
85 using Mat3 = Eigen::Matrix<double, 3, 3>;
88 using Mat23 = Eigen::Matrix<double, 2, 3, Eigen::DontAlign>;
89 using Mat34 = Eigen::Matrix<double, 3, 4, Eigen::DontAlign>;
90 using Vec2 = Eigen::Matrix<double, 2, 1, Eigen::DontAlign>;
91 using Vec4 = Eigen::Matrix<double, 4, 1, Eigen::DontAlign>;
92 using Vec6 = Eigen::Matrix<double, 6, 1, Eigen::DontAlign>;
93 #else // 64 bits compiler
94 using Mat23 = Eigen::Matrix<double, 2, 3>;
95 using Mat34 = Eigen::Matrix<double, 3, 4>;
96 using Vec2 = Eigen::Vector2d;
97 using Vec4 = Eigen::Vector4d;
98 using Vec6 = Eigen::Matrix<double, 6, 1>;
101 using Mat4 = Eigen::Matrix<double, 4, 4>;
102 using Matu = Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic>;
104 using RMat3 = Eigen::Matrix<double, 3, 3, Eigen::RowMajor>;
107 using Mat = Eigen::MatrixXd;
108 using Vec = Eigen::VectorXd;
109 using Vecu = Eigen::Matrix<unsigned int, Eigen::Dynamic, 1>;
110 using Matf = Eigen::MatrixXf;
111 using Vecf = Eigen::VectorXf;
112 using Vecb = Eigen::Matrix<bool, Eigen::Dynamic, 1>;
114 using Mat2X = Eigen::Matrix<double, 2, Eigen::Dynamic>;
115 using Mat3X = Eigen::Matrix<double, 3, Eigen::Dynamic>;
116 using Mat4X = Eigen::Matrix<double, 4, Eigen::Dynamic>;
118 using MatX9 = Eigen::Matrix<double, Eigen::Dynamic, 9>;
119 using Mat9 = Eigen::Matrix<double, 9, 9>;
122 using sMat = Eigen::SparseMatrix<double>;
123 using sRMat = Eigen::SparseMatrix<double, Eigen::RowMajor>;
140 inline T
clamp(
const T& val,
const T& min,
const T& max)
142 return std::max(min, std::min(val, max));
146 inline bool isSimilar(
double a,
double b)
148 const double diff = a - b;
149 return std::abs(diff) < 1e-8;
151 inline bool isSimilar(
float a,
float b)
153 const float diff = a - b;
154 return std::abs(diff) < 1e-8f;
172 Mat3 RotationAroundX(
double angle);
175 Mat3 RotationAroundY(
double angle);
178 Mat3 RotationAroundZ(
double angle);
180 Mat3 rotationXYZ(
double angleX,
double angleY,
double angleZ);
184 inline T degreeToRadian(T degree)
186 static_assert(std::is_floating_point<T>::value,
"degreeToRadian: must be floating point.");
187 return degree * boost::math::constants::pi<T>() / 180.0;
192 inline T radianToDegree(T radian)
194 static_assert(std::is_floating_point<T>::value,
"radianToDegree: must be floating point.");
195 return radian / boost::math::constants::pi<T>() * 180.0;
211 inline double SIGN(
double x) {
return x < 0.0 ? -1.0 : 1.0; }
215 template<
typename TVec>
216 inline double NormL1(
const TVec& x)
218 return x.array().abs().sum();
223 template<
typename TVec>
224 inline double NormL2(
const TVec& x)
231 template<
typename TVec>
232 inline double NormLInfinity(
const TVec& x)
234 return x.array().abs().maxCoeff();
237 template<
typename TVec>
238 inline double DistanceL1(
const TVec& x,
const TVec& y)
240 return (x - y).array().abs().sum();
243 template<
typename TVec>
244 inline double DistanceL2(
const TVec& x,
const TVec& y)
246 return (x - y).norm();
249 template<
typename TVec>
250 inline double DistanceLInfinity(
const TVec& x,
const TVec& y)
252 return NormLInfinity(x - y);
255 template<
typename TVec>
256 inline bool AreVecNearEqual(
const TVec& x,
const TVec& y,
const double epsilon)
258 assert(x.cols() == y.cols());
259 for (
typename TVec::Index i = 0; i < x.cols(); ++i)
261 if ((y(i) - epsilon > x(i)) || (x(i) > y(i) + epsilon))
267 template<
typename TMat>
268 inline bool AreMatNearEqual(
const TMat& X,
const TMat& Y,
const double epsilon)
270 assert(X.cols() == Y.cols());
271 assert(X.rows() == Y.rows());
272 for (
typename TMat::Index i = 0; i < X.rows(); ++i)
274 for (
typename TMat::Index j = 0; j < X.cols(); ++j)
276 if ((Y(i, j) - epsilon > X(i, j)) || (X(i, j) > Y(i, j) + epsilon))
285 Mat3 LookAt(
const Vec3& center,
const Vec3& up = Vec3::UnitY());
287 Mat3 LookAt2(
const Vec3& eyePosition3D,
const Vec3& center3D = Vec3::Zero(),
const Vec3& upVector3D = Vec3::UnitY());
289 #define SUM_OR_DYNAMIC(x, y) (x == Eigen::Dynamic || y == Eigen::Dynamic) ? Eigen::Dynamic : (x + y)
291 template<
typename Derived1,
typename Derived2>
294 using Scalar =
typename Derived1::Scalar;
298 RowsAtCompileTime = Derived1::RowsAtCompileTime,
299 ColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::ColsAtCompileTime, Derived2::ColsAtCompileTime),
300 Options = Derived1::Flags & Eigen::RowMajorBit ? Eigen::RowMajor : 0,
301 MaxRowsAtCompileTime = Derived1::MaxRowsAtCompileTime,
302 MaxColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxColsAtCompileTime, Derived2::MaxColsAtCompileTime)
304 typedef Eigen::Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime> type;
307 template<
typename Derived1,
typename Derived2>
308 typename hstack_return<Derived1, Derived2>::type HStack(
const Eigen::MatrixBase<Derived1>& lhs,
const Eigen::MatrixBase<Derived2>& rhs)
310 typename hstack_return<Derived1, Derived2>::type res;
311 res.resize(lhs.rows(), lhs.cols() + rhs.cols());
316 template<
typename Derived1,
typename Derived2>
319 using Scalar =
typename Derived1::Scalar;
323 RowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::RowsAtCompileTime, Derived2::RowsAtCompileTime),
324 ColsAtCompileTime = Derived1::ColsAtCompileTime,
325 Options = Derived1::Flags & Eigen::RowMajorBit ? Eigen::RowMajor : 0,
326 MaxRowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxRowsAtCompileTime, Derived2::MaxRowsAtCompileTime),
327 MaxColsAtCompileTime = Derived1::MaxColsAtCompileTime
329 typedef Eigen::Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options, MaxRowsAtCompileTime, MaxColsAtCompileTime> type;
332 template<
typename Derived1,
typename Derived2>
333 typename vstack_return<Derived1, Derived2>::type VStack(
const Eigen::MatrixBase<Derived1>& lhs,
const Eigen::MatrixBase<Derived2>& rhs)
335 typename vstack_return<Derived1, Derived2>::type res;
336 res.resize(lhs.rows() + rhs.rows(), lhs.cols());
340 #undef SUM_OR_DYNAMIC
342 template<
typename TMat>
343 inline double FrobeniusNorm(
const TMat& A)
348 template<
typename TMat>
349 inline double FrobeniusDistance(
const TMat& A,
const TMat& B)
351 return FrobeniusNorm(A - B);
355 double CosinusBetweenMatrices(
const TMat& a,
const TMat& b)
357 return (a.array() * b.array()).sum() / FrobeniusNorm(a) / FrobeniusNorm(b);
370 void pick(std::vector<T>& result,
const std::vector<T>& input,
const std::vector<
typename std::vector<T>::size_type>& selection)
372 result.reserve(selection.size());
374 selection.begin(), selection.end(), std::back_inserter(result), [&input](
typename std::vector<T>::size_type idx) { return input.at(idx); });
377 void MeanAndVarianceAlongRows(
const Mat& A, Vec* mean_pointer, Vec* variance_pointer);
379 bool exportMatToTextFile(
const Mat& mat,
const std::string& filename,
const std::string& sPrefix =
"A");
381 inline int is_finite(
const double val)
386 return std::isfinite(val);
404 void SplitRange(
const T range_start,
const T range_end,
const int nb_split, std::vector<T>& d_range)
406 const T range_length = range_end - range_start;
407 if (range_length < nb_split)
409 d_range.push_back(range_start);
410 d_range.push_back(range_end);
414 const T delta_range = range_length / nb_split;
416 d_range.push_back(range_start);
417 for (
int i = 1; i < nb_split; ++i)
419 d_range.push_back(range_start + i * delta_range);
421 d_range.push_back(range_end);
426 constexpr T divideRoundUp(T x, T y)
428 static_assert(std::is_integral<T>::value,
"divideRoundUp only works with integer arguments");
430 const auto xPos = x >= 0;
431 const auto yPos = y >= 0;
434 return x / y + T((x % y) != 0);