SCIP-SDP  3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
lapack_sdpa.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of SCIPSDP - a solving framework for mixed-integer */
4 /* semidefinite programs based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2017 Discrete Optimization, TU Darmstadt */
9 /* */
10 /* */
11 /* This program is free software; you can redistribute it and/or */
12 /* modify it under the terms of the GNU Lesser General Public License */
13 /* as published by the Free Software Foundation; either version 3 */
14 /* of the License, or (at your option) any later version. */
15 /* */
16 /* This program is distributed in the hope that it will be useful, */
17 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
18 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
19 /* GNU Lesser General Public License for more details. */
20 /* */
21 /* You should have received a copy of the GNU Lesser General Public License */
22 /* along with this program; if not, write to the Free Software */
23 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
24 /* */
25 /* */
26 /* Based on SCIP - Solving Constraint Integer Programs */
27 /* Copyright (C) 2002-2017 Zuse Institute Berlin */
28 /* SCIP is distributed under the terms of the SCIP Academic Licence, */
29 /* see file COPYING in the SCIP distribution. */
30 /* */
31 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32 
33 /* #define SCIP_DEBUG*/
34 /* #define SCIP_MORE_DEBUG*/
35 
43 #include <assert.h>
44 
45 #include "lapack.h"
46 #include "config.h" /* for F77_FUNC */
47 
48 #include "scip/def.h"
49 #include "blockmemshell/memory.h"
50 #include "scip/type_retcode.h"
51 
52 /* turn off lint warnings for whole file: */
53 /*lint --e{788,818}*/
54 
55 typedef long long int LAPACKINTTYPE;
56 #define SDPA_VERSION 738
57 
59 #define BMS_CALL(x) do \
60  { \
61  if( NULL == (x) ) \
62  { \
63  SCIPerrorMessage("No memory in function call\n"); \
64  return SCIP_NOMEMORY; \
65  } \
66  } \
67  while( FALSE )
68 
70 #define SCIP_RealTOINT(x) ((LAPACKINTTYPE) (x + 0.5))
71 
72 /*
73  * BLAS/LAPACK Calls
74  */
75 
80 void F77_FUNC(dsyevr, DSYEVR)(
81  char* JOBZ, char* RANGE, char* UPLO,
82  LAPACKINTTYPE* N, SCIP_Real* A, LAPACKINTTYPE* LDA,
83  SCIP_Real* VL, SCIP_Real* VU,
85  SCIP_Real* ABSTOL, LAPACKINTTYPE* M, SCIP_Real* W, SCIP_Real* Z,
86  LAPACKINTTYPE* LDZ, LAPACKINTTYPE* ISUPPZ, SCIP_Real* WORK,
87  LAPACKINTTYPE* LWORK, LAPACKINTTYPE* IWORK, LAPACKINTTYPE* LIWORK,
88  int* INFO );
89 
90 
92 void F77_FUNC(dgemv, DGEMV)(char* TRANS, LAPACKINTTYPE* M,
93  LAPACKINTTYPE* N, SCIP_Real* ALPHA, SCIP_Real* A, LAPACKINTTYPE* LDA,
94  SCIP_Real* X, LAPACKINTTYPE* INCX, SCIP_Real* BETA, SCIP_Real* Y, LAPACKINTTYPE* INCY);
95 
96 
100 /*
101  * Functions
102  */
103 
108 SCIP_RETCODE SCIPlapackComputeIthEigenvalue(
109  BMS_BUFMEM* bufmem,
110  SCIP_Bool geteigenvectors,
111  int n,
112  SCIP_Real* A,
113  int i,
114  SCIP_Real* eigenvalue,
115  SCIP_Real* eigenvector
116  )
117 {
118  LAPACKINTTYPE N;
119 #if ( SDPA_VERSION == 740 )
120  LAPACKINTTYPE INFO;
121 #else
122  int INFO;
123 #endif
124  char JOBZ;
125  char RANGE;
126  char UPLO;
127  LAPACKINTTYPE LDA;
128  SCIP_Real* WORK;
129  LAPACKINTTYPE LWORK;
130  LAPACKINTTYPE* IWORK;
131  LAPACKINTTYPE LIWORK;
132  SCIP_Real* WTMP;
133  SCIP_Real ABSTOL;
134  LAPACKINTTYPE IL;
135  LAPACKINTTYPE IU;
136  LAPACKINTTYPE M;
137  LAPACKINTTYPE LDZ;
138  SCIP_Real WSIZE;
139  LAPACKINTTYPE WISIZE;
140  SCIP_Real VL;
141  SCIP_Real VU;
142  LAPACKINTTYPE* ISUPPZ;
143 
144  assert( bufmem != NULL );
145  assert( n > 0 );
146  assert( A != NULL );
147  assert( 0 < i && i <= n );
148  assert( eigenvalue != NULL );
149  assert( ( ! geteigenvectors) || eigenvector != NULL );
150 
151  N = n;
152  JOBZ = geteigenvectors ? 'V' : 'N';
153  RANGE = 'I';
154  UPLO = 'L';
155  LDA = n;
156  ABSTOL = 0.0;
157  IL = i;
158  IU = i;
159  M = 1;
160  LDZ = n;
161 
162  /* standard LAPACK workspace query, to get the amount of needed memory */
163  LWORK = -1LL;
164  LIWORK = -1LL;
165 
166  /* this computes the internally needed memory and returns this as (the first entries of [the 1x1 arrays]) WSIZE and WISIZE */
167  F77_FUNC(dsyevr, DSYEVR)( &JOBZ, &RANGE, &UPLO,
168  &N, NULL, &LDA,
169  NULL, NULL,
170  &IL, &IU,
171  &ABSTOL, &M, NULL, NULL,
172  &LDZ, NULL, &WSIZE,
173  &LWORK, &WISIZE, &LIWORK,
174  &INFO );
175 
176  if ( INFO != 0 )
177  {
178  SCIPerrorMessage("There was an error when calling DSYEVR. INFO = %d\n", INFO);
179  return SCIP_ERROR;
180  }
181 
182  /* allocate workspace */
183  LWORK = SCIP_RealTOINT(WSIZE);
184  LIWORK = WISIZE;
185 
186  BMS_CALL( BMSallocBufferMemoryArray(bufmem, &WORK, (int) LWORK) );
187  BMS_CALL( BMSallocBufferMemoryArray(bufmem, &IWORK, (int) LIWORK) );
188  BMS_CALL( BMSallocBufferMemoryArray(bufmem, &WTMP, (int) N) );
189  BMS_CALL( BMSallocBufferMemoryArray(bufmem, &ISUPPZ, 2) ); /*lint !e506*/
190 
191  /* call the function */
192  VL = -1e20;
193  VU = 1e20;
194 
195  F77_FUNC(dsyevr, DSYEVR)( &JOBZ, &RANGE, &UPLO,
196  &N, A, &LDA,
197  &VL, &VU,
198  &IL, &IU,
199  &ABSTOL, &M, WTMP, eigenvector,
200  &LDZ, ISUPPZ, WORK,
201  &LWORK, IWORK, &LIWORK,
202  &INFO );
203 
204  if ( INFO != 0 )
205  {
206  SCIPerrorMessage("There was an error when calling DSYEVR. INFO = %d\n", INFO);
207  return SCIP_ERROR;
208  }
209 
210  /* handle output */
211  *eigenvalue = WTMP[0];
212 
213  /* free memory */
214  BMSfreeBufferMemoryArray(bufmem, &ISUPPZ);
215  BMSfreeBufferMemoryArray(bufmem, &WTMP);/*lint !e737*/
216  BMSfreeBufferMemoryArray(bufmem, &IWORK);/*lint !e737*/
217  BMSfreeBufferMemoryArray(bufmem, &WORK);/*lint !e737*/
218 
219  return SCIP_OKAY;
220 }
221 
224  int nrows,
225  int ncols,
226  SCIP_Real* matrix,
227  SCIP_Real* vector,
228  SCIP_Real* result
229  )
230 {
231  char TRANS;
232  LAPACKINTTYPE M;
233  LAPACKINTTYPE N;
234  SCIP_Real ALPHA;
235  SCIP_Real* A;
236  LAPACKINTTYPE LDA;
237  SCIP_Real* X;
238  LAPACKINTTYPE INCX;
239  SCIP_Real BETA;
240  SCIP_Real* Y;
241  LAPACKINTTYPE INCY;
242 
243  TRANS = 'N';
244  M = nrows;
245  N = ncols;
246  ALPHA = 1.0;
247  A = matrix;
248  LDA = nrows;
249  X = vector;
250  INCX = 1;
251  BETA = 0.0;
252  Y = result;
253  INCY = 1;
254 
255  F77_FUNC(dgemv, DGEMV)(&TRANS, &M, &N, &ALPHA, A, &LDA, X, &INCX, &BETA, Y, &INCY);
256 
257  return SCIP_OKAY;
258 }
259 
long long int LAPACKINTTYPE
Definition: lapack_sdpa.c:55
EXTERN SCIP_RETCODE SCIPlapackComputeIthEigenvalue(BMS_BUFMEM *bufmem, SCIP_Bool geteigenvectors, int n, SCIP_Real *A, int i, SCIP_Real *eigenvalue, SCIP_Real *eigenvector)
Macros for calling Fortran-functions.
SCIP_RETCODE SCIPlapackMatrixVectorMult(int nrows, int ncols, SCIP_Real *matrix, SCIP_Real *vector, SCIP_Real *result)
Definition: lapack_sdpa.c:223
#define BMS_CALL(x)
Definition: lapack_sdpa.c:59
#define SCIP_RealTOINT(x)
Definition: lapack_sdpa.c:70
#define F77_FUNC(name, NAME)
Definition: config.h:43
interface methods for eigenvector computation and matrix multiplication using different versions of L...