bool pinv_damped(const MatrixD &A, MatrixD *invA, Scalar lambda_max, Scalar eps) { //A (m x n) usually comes from a redundant task jacobian, therfore we consider m<n int m = A.rows() - 1; VectorD sigma; //vector of singular values Scalar lambda2; int r = 0; JacobiSVD<MatrixD> svd_A(A.transpose(), ComputeThinU | ComputeThinV); sigma = svd_A.singularValues(); if (((m > 0) && (sigma(m) > eps)) || ((m == 0) && (A.array().abs() > eps).any())) { for (int i = 0; i <= m; i++) { sigma(i) = 1.0 / sigma(i); } (*invA) = svd_A.matrixU() * sigma.asDiagonal() * svd_A.matrixV().transpose(); return true; } else { lambda2 = (1 - (sigma(m) / eps) * (sigma(m) / eps)) * lambda_max * lambda_max; for (int i = 0; i <= m; i++) { if (sigma(i) > EPSQ) r++; sigma(i) = (sigma(i) / (sigma(i) * sigma(i) + lambda2)); } //only U till the rank MatrixD subU = svd_A.matrixU().block(0, 0, A.cols(), r); MatrixD subV = svd_A.matrixV().block(0, 0, A.rows(), r); (*invA) = subU * sigma.asDiagonal() * subV.transpose(); return false; } }
bool pinv_forBarP(const MatrixD &W, const MatrixD &P, MatrixD *inv) { MatrixD barW; int rowsBarW = 0; MatrixD tmp; bool invertible; for (int i = 0; i < W.rows(); i++) { if (W(i, i) > 0.99) { //equal to 1 (safer) rowsBarW++; barW = (MatrixD(rowsBarW, W.cols()) << barW, W.row(i)).finished(); } } tmp = barW * P * barW.transpose(); FullPivLU < MatrixD > inversePbar(tmp); invertible = inversePbar.isInvertible(); if (invertible) { (*inv) = P * barW.transpose() * inversePbar.inverse() * barW; return true; } else { (*inv) = MatrixD::Zero(W.rows(), W.rows()); return false; } }
bool pinv_QR(const MatrixD &A, MatrixD *invA, Scalar eps) { MatrixD At = A.transpose(); HouseholderQR < MatrixD > qr = At.householderQr(); int m = A.rows(); //int n = A.cols(); MatrixD Rt = MatrixD::Zero(m, m); bool invertible; MatrixD hR = (MatrixD) qr.matrixQR(); MatrixD Y = ((MatrixD) qr.householderQ()).leftCols(m); //take the useful part of R for (int i = 0; i < m; i++) { for (int j = 0; j <= i; j++) Rt(i, j) = hR(j, i); } FullPivLU < MatrixD > invRt(Rt); invertible = fabs(invRt.determinant()) > eps; if (invertible) { *invA = Y * invRt.inverse(); return true; } else { return false; } }
bool OSNSVelocityIK::isOptimal(int priority, const VectorD& dotQ, const MatrixD& tildeP, MatrixD* W, VectorD* dotQn, double eps) { VectorD barMu; bool isOptimal = true; barMu = tildeP.transpose() * dotQ; for (int i = 0; i < n_dof; i++) { if ((*W)(i, i) < 0.1) { //equal to 0.0 (safer) if (abs(dotQ(i) - dotQmax(i)) < eps) barMu(i) = -barMu(i); if (barMu(i) < 0.0) { (*W)(i, i) = 1.0; (*dotQn)(i) = 0.0; isOptimal = false; } } } return isOptimal; }
bool pinv(const MatrixD &A, MatrixD *invA, Scalar eps) { //A (m x n) usually comes from a redundant task jacobian, therfore we consider m<n int m = A.rows() - 1; VectorD sigma; //vector of singular values JacobiSVD<MatrixD> svd_A(A.transpose(), ComputeThinU | ComputeThinV); sigma = svd_A.singularValues(); if (((m > 0) && (sigma(m) > eps)) || ((m == 0) && (A.array().abs() > eps).any())) { for (int i = 0; i <= m; i++) { sigma(i) = 1.0 / sigma(i); } (*invA) = svd_A.matrixU() * sigma.asDiagonal() * svd_A.matrixV().transpose(); return true; } else { return false; } }