Crocoddyl
 
Loading...
Searching...
No Matches
math.hpp
1
2// BSD 3-Clause License
3//
4// Copyright (C) 2019, LAAS-CNRS
5// Copyright note valid unless otherwise stated in individual files.
6// All rights reserved.
8
9#ifndef CROCODDYL_CORE_UTILS_MATH_HPP_
10#define CROCODDYL_CORE_UTILS_MATH_HPP_
11
12#include <Eigen/Dense>
13#include <algorithm>
14#include <boost/type_traits.hpp>
15#include <limits>
16
17// fwd
18
19template <typename MatrixLike,
20 bool value =
21 boost::is_floating_point<typename MatrixLike::Scalar>::value>
23 typedef typename MatrixLike::Scalar Scalar;
24 typedef typename MatrixLike::RealScalar RealScalar;
25
26 static MatrixLike run(const Eigen::MatrixBase<MatrixLike>& a,
27 const RealScalar& epsilon) {
28 using std::max;
29 Eigen::JacobiSVD<MatrixLike> svd(a,
30 Eigen::ComputeThinU | Eigen::ComputeThinV);
31 RealScalar tolerance = epsilon *
32 static_cast<Scalar>(max(a.cols(), a.rows())) *
33 svd.singularValues().array().abs()(0);
34 return svd.matrixV() *
35 (svd.singularValues().array().abs() > tolerance)
36 .select(svd.singularValues().array().inverse(), 0)
37 .matrix()
38 .asDiagonal() *
39 svd.matrixU().adjoint();
40 }
41};
42
43template <typename MatrixLike>
44struct pseudoInverseAlgo<MatrixLike, false> {
45 typedef typename MatrixLike::Scalar Scalar;
46 typedef typename MatrixLike::RealScalar RealScalar;
47
48 static MatrixLike run(const Eigen::MatrixBase<MatrixLike>& a,
49 const RealScalar&) {
50 return Eigen::MatrixBase<MatrixLike>::Zero(a.rows(), a.cols());
51 }
52};
53
54template <typename MatrixLike>
55MatrixLike pseudoInverse(
56 const Eigen::MatrixBase<MatrixLike>& a,
57 const typename MatrixLike::RealScalar& epsilon =
58 Eigen::NumTraits<typename MatrixLike::Scalar>::dummy_precision()) {
59 return pseudoInverseAlgo<MatrixLike>::run(a, epsilon);
60}
61
62#endif // CROCODDYL_CORE_UTILS_MATH_HPP_