C++ 使用犰狳和qpOASES时引发异常
我有一个二次规划优化问题,我正在用Qpoas解决。这里有一个矩阵X,我需要先处理,所以我使用犰狳和常规的arma::pinv来计算Moor-Penrose伪逆 问题是:我把矩阵X写在一个文件中,然后在一个单独的程序(比如test.cpp)中读取它,这个程序在任何方面都不依赖于Qpoas。常规pinv运行良好C++ 使用犰狳和qpOASES时引发异常,c++,armadillo,C++,Armadillo,我有一个二次规划优化问题,我正在用Qpoas解决。这里有一个矩阵X,我需要先处理,所以我使用犰狳和常规的arma::pinv来计算Moor-Penrose伪逆 问题是:我把矩阵X写在一个文件中,然后在一个单独的程序(比如test.cpp)中读取它,这个程序在任何方面都不依赖于Qpoas。常规pinv运行良好 #include <iostream> #include <fstream> #include <armadillo>
#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
}
运行良好:
./test.xxx
汇编:
g++ test.cpp -o test.xxx -larmadillo -lqpOASES
引发异常(由于计算pinv失败):
因此,我怀疑一些冲突-似乎使用-lqpOASES也会影响犰狳中的某些旗帜?有什么想法吗?LAPACK/BLAS中是否存在可能改变犰狳设置的依赖项或内部标志?谢谢你抽出时间
以下是arma::pinv函数的文档:
我通过从Eigen而不是犰狳计算pinv来解决这个问题 基于此错误报告,我用于Eigen的函数定义: 是:
模板
本征::矩阵XXD pinv(常数矩阵类型a,双ε=标准::数值极限::ε()
{
本征::雅可比色差<_矩阵uu类型u>svd(a,本征::computetinu |本征::computetinv);
双公差=epsilon*std::max(a.cols(),a.rows())*svd.singularValues().array().abs()(0);
返回
svd.matrixV()*(svd.singularValues().array().abs()>公差)。选择(svd.singularValues().array().Reverse(),0.matrix().asDiagonal()*svd.matrixU().adjoint();
}
如果有人在Qpoas内使用BLAS/LAPACK,问题也可以解决。在文件qpOASES/make_linux中,使用#system或replacement BLAS/LAPACK REPLACE_LINALG=0
g++ test.cpp -o test.xxx -larmadillo -lqpOASES
./test.xxx
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();
}