我使用qpOASES解决了二次规划优化问题。在那里存在一个我需要预处理的矩阵X,所以我使用Armadillo和那里的例程arma :: pinv来计算Moor-Penrose伪逆。
问题:我在一个文件中写了矩阵X,然后我在一个单独的程序(比如test.cpp)中读取它,它不依赖于qpOASES。例程pinv运行正常。
#include <iostream>
#include <fstream>
#include <armadillo>
#include <string>
using namespace std;
using namespace arma;
int main(){
// Read design matrix.
int NRows = 199;
int NFields = 26;
string flname_in = "chol_out_2_data";
mat A (NRows,NFields);
for (int i=0; i < NRows; ++i)
for (int j=0; j < NFields; ++j)
myin >> A(i,j) ;
// Calculate pseudoinverse
mat M;
pinv(M,A); // <========= THIS fails when I use flag: -lqpOASES
}
当我在执行QP优化的文件中包含相同的例程(比如true_QP.cpp)时,由于pinv无法计算伪逆,我得到运行时错误。我做了大量的测试,文件在OK中读取,值也是一样。
我通过以下方式跟踪了存在冲突的问题:我编译了不依赖于qpOASES(test.cpp - 如上所述)的程序,并使用-lqpOASES标志,然后,代码给出了运行时错误。
即编译:
g++ test.cpp -o test.xxx -larmadillo
运行良好:
./test.xxx
编译:
g++ test.cpp -o test.xxx -larmadillo -lqpOASES
抛出异常(由于计算pinv失败):
./test.xxx
因此我怀疑有些冲突 - 似乎使用-lqpOASES也会影响犰狳中的某些旗帜?有任何想法吗?是否存在LAPACK / BLAS中的某些依赖或内部的某些标志可能会改变Armadillo的设置?感谢您的时间。
以下是arma :: pinv函数的文档: http://arma.sourceforge.net/docs.html#pinv
答案 0 :(得分:0)
我通过计算来自Eigen而不是Armadillo的pinv解决了这个问题。
我用于Eigen的函数定义,基于此错误报告: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=257
是:
template<typename _Matrix_Type_>
Eigen::MatrixXd pinv(const _Matrix_Type_ &a, double epsilon =std::numeric_limits<double>::epsilon())
{
Eigen::JacobiSVD< _Matrix_Type_ > svd(a ,Eigen::ComputeThinU | Eigen::ComputeThinV);
double tolerance = epsilon * std::max(a.cols(), a.rows()) *svd.singularValues().array().abs()(0);
return
svd.matrixV() * (svd.singularValues().array().abs() > tolerance).select(svd.singularValues().array().inverse(), 0).matrix().asDiagonal() * svd.matrixU().adjoint();
}