библиотека Lapack для оптимизации scip

У меня есть задача квадратичной оптимизации с линейными ограничениями, которую я хочу решить с помощью SCIP. Матрица оптимизации, которую я хочу минимизировать, является положительной полуопределенной (если быть точным, это дисперсия определенных переменных). У меня проблема с файлом в формате CPLEX LP, и когда я оптимизирую в SCIP, я получаю сообщение

Quadratic constraint handler does not have LAPACK for eigenvalue computation. Will assume
that matrices (with size > 2x2) are indefinite.

Итак, SCIP начинает оптимизацию, предполагая, что матрица неопределенная и занимает много времени. Я установил LAPACK и даже скопировал liblapack.a файл в папку lib, где находятся SCIP исходный код и двоичные файлы, и переустановил SCIP. Но я продолжаю получать вышеуказанное сообщение.

Есть ли способ заставить SCIP использовать LAPACK библиотеку? Я считаю, что оптимизация будет действительно быстрой, если SCIP сможет выяснить, что матрица является положительной полуопределенной.


person Sagar Jha    schedule 17.11.2014    source источник


Ответы (2)


Если вы хотите немного подправить SCIP, чтобы использовать вашу Lapack lib без предоставления полного Ipopt (хотя его относительно легко построить на * nix и, как указал Матмилтен, это может улучшить производительность), вот патч, который вы можете попробовать:

diff --git a/src/scip/cons_quadratic.c b/src/scip/cons_quadratic.c
index 93ba359..795bade 100644
--- a/src/scip/cons_quadratic.c
+++ b/src/scip/cons_quadratic.c
@@ -46,7 +46,7 @@
 #include "scip/heur_trysol.h"
 #include "scip/debug.h"
 #include "nlpi/nlpi.h"
-#include "nlpi/nlpi_ipopt.h"
+/*#include "nlpi/nlpi_ipopt.h" */

 /* constraint handler properties */
 #define CONSHDLR_NAME          "quadratic"
@@ -4257,6 +4257,71 @@ void checkCurvatureEasy(
       *determined = FALSE;
 }

+#define F77_FUNC(a,A) a##_
+
+   /** LAPACK Fortran subroutine DSYEV */
+   void F77_FUNC(dsyev,DSYEV)(
+      char*                 jobz,               /**< 'N' to compute eigenvalues only, 'V' to compute eigenvalues and eigenvectors */
+      char*                 uplo,               /**< 'U' if upper triangle of A is stored, 'L' if lower triangle of A is stored */
+      int*                  n,                  /**< dimension */
+      double*               A,                  /**< matrix A on entry; orthonormal eigenvectors on exit, if jobz == 'V' and info == 0; if jobz == 'N', then the matrix data is destroyed */
+      int*                  ldA,                /**< leading dimension, probably equal to n */
+      double*               W,                  /**< buffer for the eigenvalues in ascending order */
+      double*               WORK,               /**< workspace array */
+      int*                  LWORK,              /**< length of WORK; if LWORK = -1, then the optimal workspace size is calculated and returned in WORK(1) */
+      int*                  info                /**< == 0: successful exit; < 0: illegal argument at given position; > 0: failed to converge */
+      );
+
+/** Calls Lapacks Dsyev routine to compute eigenvalues and eigenvectors of a dense matrix. 
+ */
+static
+SCIP_RETCODE LapackDsyev(
+   SCIP_Bool             computeeigenvectors,/**< should also eigenvectors should be computed ? */
+   int                   N,                  /**< dimension */
+   SCIP_Real*            a,                  /**< matrix data on input (size N*N); eigenvectors on output if computeeigenvectors == TRUE */
+   SCIP_Real*            w                   /**< buffer to store eigenvalues (size N) */
+   )
+{
+   int     INFO;
+   char    JOBZ = computeeigenvectors ? 'V' : 'N';
+   char    UPLO = 'L';
+   int     LDA  = N;
+   double* WORK = NULL;
+   int     LWORK;
+   double  WORK_PROBE;
+   int     i;
+
+   /* First we find out how large LWORK should be */
+   LWORK = -1;
+   F77_FUNC(dsyev,DSYEV)(&JOBZ, &UPLO, &N, a, &LDA, w, &WORK_PROBE, &LWORK, &INFO);
+   if( INFO != 0 )
+   {
+      SCIPerrorMessage("There was an error when calling DSYEV. INFO = %d\n", INFO);
+      return SCIP_ERROR;
+   }
+
+   LWORK = (int) WORK_PROBE;
+   assert(LWORK > 0);
+
+   SCIP_ALLOC( BMSallocMemoryArray(&WORK, LWORK) );
+
+   for( i = 0; i < LWORK; ++i )
+      WORK[i] = i;
+
+   F77_FUNC(dsyev,DSYEV)(&JOBZ, &UPLO, &N, a, &LDA, w, WORK, &LWORK, &INFO);
+
+   BMSfreeMemoryArray(&WORK);
+
+   if( INFO != 0 )
+   {
+      SCIPerrorMessage("There was an error when calling DSYEV. INFO = %d\n", INFO);
+      return SCIP_ERROR;
+   }
+
+   return SCIP_OKAY;
+}
+
+
 /** checks a quadratic constraint for convexity and/or concavity */
 static
 SCIP_RETCODE checkCurvature(
@@ -4343,7 +4408,7 @@ SCIP_RETCODE checkCurvature(
       return SCIP_OKAY;
    }

-   if( SCIPisIpoptAvailableIpopt() )
+   if( TRUE )
    {
       for( i = 0; i < consdata->nbilinterms; ++i )
       {
@@ -4479,7 +4544,7 @@ SCIP_RETCODE checkFactorable(
       return SCIP_OKAY;

    /* need routine to compute eigenvalues/eigenvectors */
-   if( !SCIPisIpoptAvailableIpopt() )
+   if( !TRUE )
       return SCIP_OKAY;

    SCIP_CALL( consdataSortQuadVarTerms(scip, consdata) );
@@ -9395,7 +9460,7 @@ SCIP_DECL_CONSINITSOL(consInitsolQuadratic)
       SCIP_CALL( SCIPcatchEvent(scip, SCIP_EVENTTYPE_SOLFOUND, eventhdlr, (SCIP_EVENTDATA*)conshdlr, &conshdlrdata->newsoleventfilterpos) );
    }

-   if( nconss != 0 && !SCIPisIpoptAvailableIpopt() && !SCIPisInRestart(scip) )
+   if( nconss != 0 && !TRUE && !SCIPisInRestart(scip) )
    {
       SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Quadratic constraint handler does not have LAPACK for eigenvalue computation. Will assume that matrices (with size > 2x2) are indefinite.\n");
    }

Используйте USRLDFLAGS="-llapack -lblas" с make.

person stefan    schedule 17.11.2014
comment
Спасибо! У меня это сработало. Я обнаружил, что установка ipopt (на ubuntu) слишком хлопотна. Единственное изменение заключалось в ссылке на библиотеку gfortran, которая устанавливает scip с USRLDFLAGS = -llapack -lblas -lgfortran. - person Sagar Jha; 17.11.2014

В настоящее время SCIP может использовать LAPACK только через Ipopt. Когда SCIP скомпилирован с поддержкой Ipopt, производительность при решении нелинейных задач обычно выше, поэтому это определенно рекомендуется. Запустить

make IPOPT=true

и убедитесь, что у вас установлен Ipopt заранее.

person mattmilten    schedule 17.11.2014
comment
Спасибо, но установка ipopt казалась слишком хлопотной. Другое решение сработало для меня. - person Sagar Jha; 17.11.2014