25#ifndef LIBMV_NUMERIC_NUMERIC_H
26#define LIBMV_NUMERIC_NUMERIC_H
28#include <Eigen/Cholesky>
30#include <Eigen/Eigenvalues>
31#include <Eigen/Geometry>
39#if !defined(__MINGW64__)
40# if defined(_WIN32) || defined(__APPLE__) || defined(__NetBSD__) || \
42inline void sincos(
double x,
double* sinx,
double* cosx) {
49#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
50inline long lround(
double d) {
51 return (
long)(d > 0 ? d + 0.5 :
ceil(d - 0.5));
54inline int round(
double d) {
55 return (d > 0) ? int(d + 0.5) : int(d - 0.5);
58typedef unsigned int uint;
63typedef Eigen::MatrixXd
Mat;
64typedef Eigen::VectorXd
Vec;
66typedef Eigen::MatrixXf
Matf;
67typedef Eigen::VectorXf
Vecf;
69typedef Eigen::Matrix<unsigned int, Eigen::Dynamic, Eigen::Dynamic>
Matu;
70typedef Eigen::Matrix<unsigned int, Eigen::Dynamic, 1>
Vecu;
71typedef Eigen::Matrix<unsigned int, 2, 1>
Vec2u;
73typedef Eigen::Matrix<double, 2, 2>
Mat2;
74typedef Eigen::Matrix<double, 2, 3>
Mat23;
75typedef Eigen::Matrix<double, 3, 3>
Mat3;
76typedef Eigen::Matrix<double, 3, 4>
Mat34;
77typedef Eigen::Matrix<double, 3, 5>
Mat35;
78typedef Eigen::Matrix<double, 4, 1>
Mat41;
79typedef Eigen::Matrix<double, 4, 3>
Mat43;
80typedef Eigen::Matrix<double, 4, 4>
Mat4;
81typedef Eigen::Matrix<double, 4, 6>
Mat46;
82typedef Eigen::Matrix<float, 2, 2>
Mat2f;
83typedef Eigen::Matrix<float, 2, 3>
Mat23f;
84typedef Eigen::Matrix<float, 3, 3>
Mat3f;
85typedef Eigen::Matrix<float, 3, 4>
Mat34f;
86typedef Eigen::Matrix<float, 3, 5>
Mat35f;
87typedef Eigen::Matrix<float, 4, 3>
Mat43f;
88typedef Eigen::Matrix<float, 4, 4>
Mat4f;
89typedef Eigen::Matrix<float, 4, 6>
Mat46f;
91typedef Eigen::Matrix<double, 3, 3, Eigen::RowMajor>
RMat3;
92typedef Eigen::Matrix<double, 4, 4, Eigen::RowMajor>
RMat4;
94typedef Eigen::Matrix<double, 2, Eigen::Dynamic>
Mat2X;
95typedef Eigen::Matrix<double, 3, Eigen::Dynamic>
Mat3X;
96typedef Eigen::Matrix<double, 4, Eigen::Dynamic>
Mat4X;
97typedef Eigen::Matrix<double, Eigen::Dynamic, 2>
MatX2;
98typedef Eigen::Matrix<double, Eigen::Dynamic, 3>
MatX3;
99typedef Eigen::Matrix<double, Eigen::Dynamic, 4>
MatX4;
100typedef Eigen::Matrix<double, Eigen::Dynamic, 5>
MatX5;
101typedef Eigen::Matrix<double, Eigen::Dynamic, 6>
MatX6;
102typedef Eigen::Matrix<double, Eigen::Dynamic, 7>
MatX7;
103typedef Eigen::Matrix<double, Eigen::Dynamic, 8>
MatX8;
104typedef Eigen::Matrix<double, Eigen::Dynamic, 9>
MatX9;
105typedef Eigen::Matrix<double, Eigen::Dynamic, 15>
MatX15;
106typedef Eigen::Matrix<double, Eigen::Dynamic, 16>
MatX16;
111typedef Eigen::Matrix<double, 5, 1>
Vec5;
112typedef Eigen::Matrix<double, 6, 1>
Vec6;
113typedef Eigen::Matrix<double, 7, 1>
Vec7;
114typedef Eigen::Matrix<double, 8, 1>
Vec8;
115typedef Eigen::Matrix<double, 9, 1>
Vec9;
116typedef Eigen::Matrix<double, 10, 1>
Vec10;
117typedef Eigen::Matrix<double, 11, 1>
Vec11;
118typedef Eigen::Matrix<double, 12, 1>
Vec12;
119typedef Eigen::Matrix<double, 13, 1>
Vec13;
120typedef Eigen::Matrix<double, 14, 1>
Vec14;
121typedef Eigen::Matrix<double, 15, 1>
Vec15;
122typedef Eigen::Matrix<double, 16, 1>
Vec16;
123typedef Eigen::Matrix<double, 17, 1>
Vec17;
124typedef Eigen::Matrix<double, 18, 1>
Vec18;
125typedef Eigen::Matrix<double, 19, 1>
Vec19;
126typedef Eigen::Matrix<double, 20, 1>
Vec20;
138typedef Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
151template <
typename TMat,
typename TVec>
160template <
typename TMat,
typename TVec>
162 Eigen::JacobiSVD<TMat> svd(*
A, Eigen::ComputeFullV);
163 (*nullspace) = svd.matrixV().col(
A->cols() - 1);
164 if (
A->rows() >=
A->cols()) {
165 return svd.singularValues()(
A->cols() - 1);
176template <
typename TMat,
typename TVec1,
typename TVec2>
178 Eigen::JacobiSVD<TMat> svd(*
A, Eigen::ComputeFullV);
179 *x1 = svd.matrixV().col(
A->cols() - 1);
180 *x2 = svd.matrixV().col(
A->cols() - 2);
181 if (
A->rows() >=
A->cols()) {
182 return svd.singularValues()(
A->cols() - 1);
191 *
A =
A->transpose().eval();
194template <
typename TVec>
196 return x.array().abs().sum();
199template <
typename TVec>
204template <
typename TVec>
206 return x.array().abs().maxCoeff();
209template <
typename TVec>
211 return (
x -
y).array().abs().sum();
214template <
typename TVec>
216 return (
x -
y).norm();
218template <
typename TVec>
220 return (
x -
y).array().abs().maxCoeff();
225template <
typename TVec>
234template <
typename TVec>
243template <
typename TVec>
270template <
typename TVec>
272 return x.asDiagonal();
275template <
typename TMat>
277 return sqrt(
A.array().abs2().sum());
280template <
typename TMat>
293 Vec* variance_pointer);
299# define SUM_OR_DYNAMIC(x, y) \
300 (x == Eigen::Dynamic || y == Eigen::Dynamic) ? Eigen::Dynamic : (x + y)
302template <
typename Derived1,
typename Derived2>
303struct hstack_return {
304 typedef typename Derived1::Scalar
Scalar;
306 RowsAtCompileTime = Derived1::RowsAtCompileTime,
307 ColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::ColsAtCompileTime,
308 Derived2::ColsAtCompileTime),
309 Options = Derived1::Flags & Eigen::RowMajorBit ? Eigen::RowMajor : 0,
310 MaxRowsAtCompileTime = Derived1::MaxRowsAtCompileTime,
311 MaxColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxColsAtCompileTime,
312 Derived2::MaxColsAtCompileTime)
314 typedef Eigen::Matrix<
Scalar,
318 MaxRowsAtCompileTime,
319 MaxColsAtCompileTime>
323template <
typename Derived1,
typename Derived2>
324typename hstack_return<Derived1, Derived2>::type
HStack(
325 const Eigen::MatrixBase<Derived1>& lhs,
326 const Eigen::MatrixBase<Derived2>&
rhs) {
327 typename hstack_return<Derived1, Derived2>::type res;
328 res.resize(lhs.rows(), lhs.cols() +
rhs.cols());
333template <
typename Derived1,
typename Derived2>
334struct vstack_return {
335 typedef typename Derived1::Scalar
Scalar;
337 RowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::RowsAtCompileTime,
338 Derived2::RowsAtCompileTime),
339 ColsAtCompileTime = Derived1::ColsAtCompileTime,
340 Options = Derived1::Flags & Eigen::RowMajorBit ? Eigen::RowMajor : 0,
341 MaxRowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxRowsAtCompileTime,
342 Derived2::MaxRowsAtCompileTime),
343 MaxColsAtCompileTime = Derived1::MaxColsAtCompileTime
345 typedef Eigen::Matrix<
Scalar,
349 MaxRowsAtCompileTime,
350 MaxColsAtCompileTime>
354template <
typename Derived1,
typename Derived2>
355typename vstack_return<Derived1, Derived2>::type
VStack(
356 const Eigen::MatrixBase<Derived1>& lhs,
357 const Eigen::MatrixBase<Derived2>&
rhs) {
358 typename vstack_return<Derived1, Derived2>::type res;
359 res.resize(lhs.rows() +
rhs.rows(), lhs.cols());
369 ((ColsLeft == Eigen::Dynamic || ColsRight == Eigen::Dynamic) \
371 : (ColsLeft + ColsRight))
375 ((RowsLeft == Eigen::Dynamic && RowsRight == Eigen::Dynamic) \
377 : ((RowsLeft == Eigen::Dynamic) ? RowsRight : RowsLeft))
380template <
typename T,
int RowsLeft,
int RowsRight,
int ColsLeft,
int ColsRight>
382 const Eigen::Matrix<T, RowsLeft, ColsLeft>&
left,
383 const Eigen::Matrix<T, RowsRight, ColsRight>& right) {
386 int m1 =
left.cols();
387 int m2 = right.cols();
389 Eigen::Matrix<T, ROWS, COLS> stacked(n, m1 + m2);
390 stacked.block(0, 0, n, m1) =
left;
391 stacked.block(0, m1, n, m2) = right;
400template <
typename T,
int RowsLeft,
int RowsRight,
int ColsLeft,
int ColsRight>
402 const Eigen::Matrix<T, ColsLeft, RowsLeft>&
top,
403 const Eigen::Matrix<T, ColsRight, RowsRight>& bottom) {
406 int n2 = bottom.rows();
409 Eigen::Matrix<T, COLS, ROWS> stacked(n1 + n2, m);
410 stacked.block(0, 0, n1, m) =
top;
411 stacked.block(n1, 0, n2, m) = bottom;
420template <
typename TTop,
typename TBot,
typename TStacked>
424 int n2 = bottom.rows();
427 stacked->resize(n1 + n2, m);
428 stacked->block(0, 0, n1, m) =
top;
429 stacked->block(n1, 0, n2, m) = bottom;
436template <
typename TMat,
typename TCols>
438 TMat compressed(
A.rows(), columns.size());
439 for (
int i = 0;
i < columns.size(); ++
i) {
440 compressed.col(
i) =
A.col(columns[
i]);
445template <
typename TMat,
typename TDest>
446void reshape(
const TMat& a,
int rows,
int cols, TDest*
b) {
447 assert(a.rows() * a.cols() == rows * cols);
448 b->resize(rows, cols);
449 for (
int i = 0;
i < rows;
i++) {
450 for (
int j = 0; j < cols; j++) {
451 (*b)(
i, j) = a[cols *
i + j];
458 return _isnan(
i) > 0;
460 return std::isnan(
i);
466template <
typename FloatType>
467FloatType
ceil0(
const FloatType& value) {
468 FloatType
result = std::ceil(std::fabs(value));
475 skew << 0, -
x(2),
x(1),
x(2), 0, -
x(0), -
x(1),
x(0), 0;
482 skew << 0, -1,
x(1), 1, 0, -
x(0);
488 double theta = euler_vector.norm();
490 return Mat3::Identity();
492 Vec3 w = euler_vector / theta;
494 return Mat3::Identity() + w_hat *
sin(theta) +
495 w_hat * w_hat * (1 -
cos(theta));
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
#define assert(assertion)
double DistanceLInfinity(const TVec &x, const TVec &y)
Eigen::Matrix< double, 19, 1 > Vec19
Eigen::Matrix< float, 3, 5 > Mat35f
Eigen::Matrix< double, 11, 1 > Vec11
double Nullspace(TMat *A, TVec *nullspace)
Eigen::Matrix< double, 6, 1 > Vec6
double NormL2(const TVec &x)
Eigen::Matrix< double, 3, 3, Eigen::RowMajor > RMat3
Eigen::Matrix< double, 13, 1 > Vec13
Mat3 CrossProductMatrix(const Vec3 &x)
double DistanceL1(const TVec &x, const TVec &y)
Eigen::Matrix< double, 10, 1 > Vec10
Mat3 RotationFromEulerVector(Vec3 euler_vector)
Returns the rotaiton matrix built from given vector of euler angles.
void TransposeInPlace(TA *A)
Eigen::Matrix< double, Eigen::Dynamic, 2 > MatX2
Eigen::Matrix< double, 4, 4 > Mat4
void VerticalStack(const TTop &top, const TBot &bottom, TStacked *stacked)
Eigen::Matrix< double, 4, 1 > Mat41
Eigen::Matrix< double, Eigen::Dynamic, 3 > MatX3
Eigen::Matrix< double, Eigen::Dynamic, 15 > MatX15
double DistanceL2(const TVec &x, const TVec &y)
Eigen::Matrix< double, 3, 3 > Mat3
void SVD(TMat *, Vec *, Mat *, Mat *)
Eigen::Matrix< double, Eigen::Dynamic, 4 > MatX4
Eigen::Matrix< double, Eigen::Dynamic, 5 > MatX5
double NormalizeL1(TVec *x)
Mat3 RotationAroundX(double angle)
Eigen::Matrix< float, 2, 2 > Mat2f
double NormLInfinity(const TVec &x)
Eigen::Matrix< float, 4, 3 > Mat43f
double FrobeniusDistance(const TMat &A, const TMat &B)
Eigen::Matrix< double, 4, 4, Eigen::RowMajor > RMat4
Eigen::Matrix< double, 14, 1 > Vec14
Eigen::Matrix< double, 4, 6 > Mat46
void MatrixColumn(const Mat &A, int i, Vec2 *v)
void MeanAndVarianceAlongRows(const Mat &A, Vec *mean_pointer, Vec *variance_pointer)
Mat23 SkewMatMinimal(const Vec2 &x)
Eigen::Matrix< T, ROWS, COLS > HStack(const Eigen::Matrix< T, RowsLeft, ColsLeft > &left, const Eigen::Matrix< T, RowsRight, ColsRight > &right)
Eigen::Matrix< double, 7, 1 > Vec7
Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > RMatf
Eigen::Matrix< double, Eigen::Dynamic, 9 > MatX9
double NormalizeLInfinity(TVec *x)
Eigen::Matrix< double, Eigen::Dynamic, 8 > MatX8
Eigen::NumTraits< double > EigenDouble
Eigen::Matrix< float, 3, 3 > Mat3f
Mat3 RotationRodrigues(const Vec3 &axis)
Eigen::Matrix< double, 2, 3 > Mat23
Eigen::Matrix< double, 3, 4 > Mat34
Eigen::Matrix< double, Eigen::Dynamic, 7 > MatX7
Eigen::Matrix< double, 8, 1 > Vec8
Eigen::Matrix< unsigned int, Eigen::Dynamic, 1 > Vecu
Mat3 SkewMat(const Vec3 &x)
Returns the skew anti-symmetric matrix of a vector.
Eigen::Matrix< double, 18, 1 > Vec18
Eigen::Matrix< double, Eigen::Dynamic, 16 > MatX16
Eigen::Matrix< double, 5, 1 > Vec5
Eigen::Matrix< double, 15, 1 > Vec15
FloatType ceil0(const FloatType &value)
Eigen::Matrix< double, 4, Eigen::Dynamic > Mat4X
Eigen::Matrix< double, 3, Eigen::Dynamic > Mat3X
Eigen::Matrix< float, 2, 3 > Mat23f
Eigen::Matrix< float, 3, 4 > Mat34f
Eigen::Matrix< double, 3, 5 > Mat35
Eigen::Matrix< unsigned int, Eigen::Dynamic, Eigen::Dynamic > Matu
double FrobeniusNorm(const TMat &A)
Eigen::Matrix< double, 12, 1 > Vec12
Eigen::Matrix< double, 16, 1 > Vec16
Eigen::Matrix< T, COLS, ROWS > VStack(const Eigen::Matrix< T, ColsLeft, RowsLeft > &top, const Eigen::Matrix< T, ColsRight, RowsRight > &bottom)
Eigen::Matrix< double, 20, 1 > Vec20
void HorizontalStack(const Mat &left, const Mat &right, Mat *stacked)
Mat3 RotationAroundZ(double angle)
void reshape(const TMat &a, int rows, int cols, TDest *b)
Eigen::Matrix< double, 9, 1 > Vec9
Eigen::Matrix< double, 2, Eigen::Dynamic > Mat2X
Mat3 RotationAroundY(double angle)
Eigen::Matrix< float, 4, 6 > Mat46f
double NormalizeL2(TVec *x)
double Nullspace2(TMat *A, TVec1 *x1, TVec2 *x2)
Eigen::Matrix< double, 17, 1 > Vec17
Eigen::Matrix< double, 2, 2 > Mat2
TMat ExtractColumns(const TMat &A, const TCols &columns)
Eigen::Matrix< float, 4, 4 > Mat4f
Eigen::Matrix< unsigned int, 2, 1 > Vec2u
Vec3 CrossProduct(const Vec3 &x, const Vec3 &y)
double NormL1(const TVec &x)
Eigen::Matrix< double, Eigen::Dynamic, 6 > MatX6
Eigen::Matrix< double, 4, 3 > Mat43