2015-06-08 3 views
0

У меня есть проблема оптимизации квадратичного программирования, которую я решаю с помощью qpOASES. В нем существует матрица X, которая мне нужна для предварительного условия, поэтому я использую Armadillo и рутинную arma :: pinv оттуда, чтобы вычислить псевдоверсию Moor-Penrose.Исключение броска при использовании Armadillo и qpOASES

Проблема: Я записываю матрицу 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 не в состоянии вычислить псевдо обратное. Я провел обширные тесты, файл читается в ОК, и значения одинаковы.

Я обнаружил проблему, которая является конфликтом следующим образом: я скомпилировал программу, которая никоим образом не зависит от 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 влияет на некоторый флаг в armadillo также? Есть идеи? Есть ли какая-либо зависимость в LAPACK/BLAS или какой-либо флаг внутри, который может изменить настройку Armadillo? Спасибо за ваше время.

Вот документация для функции армы :: pinv: http://arma.sourceforge.net/docs.html#pinv

ответ

0

я решил проблему путем вычисления pinv из Эйгена, вместо Armadillo.

Определение функции я использовал для Эйгена, на основе этого сообщения об ошибке: 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(); 
} 
+0

Проблема может быть решена если чей enanbles использование BLAS/LAPACK внутри qpOASES. В файле qpOASES/make_linux используйте # система или замена BLAS/LAPACK REPLACE_LINALG = 0 – Foivos

Смежные вопросы