使用犰狳和 qpOASES 时抛出异常

Exception throw when using Armadillo and qpOASES

我有一个二次规划优化问题,我正在用 qpOASES 解决。其中存在一个我需要预处理的矩阵 X,因此我使用 Armadillo 和那里的例程 arma::pinv 来计算 Moor-Penrose 伪逆。

问题:我将矩阵 X 写入一个文件,然后在一个不以任何方式依赖于 qpOASES 的单独程序(比如 test.cpp)中读取它。例程 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),我得到一个 运行time 错误,因为 pinv 无法计算伪逆。我做了广泛的测试,文件读取正常,值相同。

我已经通过以下方式找到了冲突问题:我编译了一个不以任何方式依赖 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

我已经通过从 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();
}