SCIP-SDP  2.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 programms based on SCIP. */
5 /* */
6 /* Copyright (C) 2011-2013 Discrete Optimization, TU Darmstadt */
7 /* EDOM, FAU Erlangen-Nürnberg */
8 /* 2014-2015 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-2015 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 typedef long long int LAPACKINTTYPE;
53 
55 #define BMS_CALL(x) do \
56  { \
57  if( NULL == (x) ) \
58  { \
59  SCIPerrorMessage("No memory in function call\n"); \
60  return SCIP_NOMEMORY; \
61  } \
62  } \
63  while( FALSE )
64 
66 #define DOUBLETOINT(x) ((LAPACKINTTYPE) (x + 0.5))
67 
68 /*
69  * BLAS/LAPACK Calls
70  */
71 
76 void F77_FUNC(dsyevr, DSYEVR)(
77  char* JOBZ, char* RANGE, char* UPLO,
78  LAPACKINTTYPE* N, double* A, LAPACKINTTYPE* LDA,
79  double* VL, double* VU,
81  double* ABSTOL, LAPACKINTTYPE* M, double* W, double* Z,
82  LAPACKINTTYPE* LDZ, LAPACKINTTYPE* ISUPPZ, double* WORK,
83  LAPACKINTTYPE* LWORK, LAPACKINTTYPE* IWORK, LAPACKINTTYPE* LIWORK,
84  int* INFO );
85 
86 
88 void F77_FUNC(dgemv, DGEMV)(char* TRANS, LAPACKINTTYPE* M,
89  LAPACKINTTYPE* N, double* ALPHA, double* A, LAPACKINTTYPE* LDA,
90  double* X, LAPACKINTTYPE* INCX, double* BETA, double* Y, LAPACKINTTYPE* INCY);
91 
92 
96 /*
97  * Functions
98  */
99 
104 SCIP_RETCODE SCIPlapackComputeIthEigenvalue(
105  BMS_BLKMEM* blkmem,
106  SCIP_Bool geteigenvectors,
107  int n,
108  SCIP_Real* A,
109  int i,
110  SCIP_Real* eigenvalue,
111  SCIP_Real* eigenvector
112  )
113 {
114  LAPACKINTTYPE N;
115  int INFO;
116  char JOBZ;
117  char RANGE;
118  char UPLO;
119  LAPACKINTTYPE LDA;
120  double* WORK;
121  LAPACKINTTYPE LWORK;
122  LAPACKINTTYPE* IWORK;
123  LAPACKINTTYPE LIWORK;
124  double* WTMP;
125  double ABSTOL;
126  LAPACKINTTYPE IL;
127  LAPACKINTTYPE IU;
128  LAPACKINTTYPE M;
129  LAPACKINTTYPE LDZ;
130  double WSIZE;
131  LAPACKINTTYPE WISIZE;
132  double VL;
133  double VU;
134  LAPACKINTTYPE* ISUPPZ;
135 
136  assert( blkmem != NULL );
137  assert( n > 0 );
138  assert( A != NULL );
139  assert( 0 < i && i <= n );
140  assert( eigenvalue != NULL );
141  assert( ( ! geteigenvectors) || eigenvector != NULL );
142 
143  N = n;
144  JOBZ = geteigenvectors ? 'V' : 'N';
145  RANGE = 'I';
146  UPLO = 'L';
147  LDA = n;
148  ABSTOL = 0.0;
149  IL = i;
150  IU = i;
151  M = 1;
152  LDZ = n;
153 
154  /* standard LAPACK workspace query, to get the amount of needed memory */
155  LWORK = -1LL;
156  LIWORK = -1LL;
157 
158  /* this computes the internally needed memory and returns this as (the first entries of [the 1x1 arrays]) WSIZE and WISIZE */
159  F77_FUNC(dsyevr, DSYEVR)( &JOBZ, &RANGE, &UPLO,
160  &N, NULL, &LDA,
161  NULL, NULL,
162  &IL, &IU,
163  &ABSTOL, &M, NULL, NULL,
164  &LDZ, NULL, &WSIZE,
165  &LWORK, &WISIZE, &LIWORK,
166  &INFO );
167 
168  if ( INFO != 0 )
169  {
170  SCIPerrorMessage("There was an error when calling DSYEVR. INFO = %d\n", INFO);
171  return SCIP_ERROR;
172  }
173 
174  /* allocate workspace */
175  LWORK = DOUBLETOINT(WSIZE);
176  LIWORK = WISIZE;
177 
178  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &WORK, (int) LWORK) );
179  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &IWORK, (int) LIWORK) );
180  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &WTMP, (int) N) );
181  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &ISUPPZ, 2) ); /*lint !e506*/
182 
183  /* call the function */
184  VL = -1e20;
185  VU = 1e20;
186 
187  F77_FUNC(dsyevr, DSYEVR)( &JOBZ, &RANGE, &UPLO,
188  &N, A, &LDA,
189  &VL, &VU,
190  &IL, &IU,
191  &ABSTOL, &M, WTMP, eigenvector,
192  &LDZ, ISUPPZ, WORK,
193  &LWORK, IWORK, &LIWORK,
194  &INFO );
195 
196  if ( INFO != 0 )
197  {
198  SCIPerrorMessage("There was an error when calling DSYEVR. INFO = %d\n", INFO);
199  return SCIP_ERROR;
200  }
201 
202  /* handle output */
203  *eigenvalue = WTMP[0];
204 
205  /* free memory */
206  BMSfreeBlockMemoryArray(blkmem, &ISUPPZ, 2);
207  BMSfreeBlockMemoryArray(blkmem, &WTMP, (int) N);
208  BMSfreeBlockMemoryArray(blkmem, &IWORK, (int) LIWORK);
209  BMSfreeBlockMemoryArray(blkmem, &WORK, (int) LWORK);
210 
211  return SCIP_OKAY;
212 }
213 
216  int nrows,
217  int ncols,
218  SCIP_Real* matrix,
219  SCIP_Real* vector,
220  SCIP_Real* result
221  )
222 {
223  char TRANS;
224  LAPACKINTTYPE M;
225  LAPACKINTTYPE N;
226  double ALPHA;
227  double* A;
228  LAPACKINTTYPE LDA;
229  double* X;
230  LAPACKINTTYPE INCX;
231  double BETA;
232  double* Y;
233  LAPACKINTTYPE INCY;
234 
235  TRANS = 'N';
236  M = nrows;
237  N = ncols;
238  ALPHA = 1.0;
239  A = matrix;
240  LDA = nrows;
241  X = vector;
242  INCX = 1;
243  BETA = 0.0;
244  Y = result;
245  INCY = 1;
246 
247  F77_FUNC(dgemv, DGEMV)(&TRANS, &M, &N, &ALPHA, A, &LDA, X, &INCX, &BETA, Y, &INCY);
248 
249  return SCIP_OKAY;
250 }
251 
long long int LAPACKINTTYPE
Definition: lapack_sdpa.c:52
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:215
#define BMS_CALL(x)
Definition: lapack_sdpa.c:55
#define DOUBLETOINT(x)
Definition: lapack_sdpa.c:66
#define F77_FUNC(name, NAME)
Definition: config.h:42
interface methods for eigenvector computation and matrix multiplication using different versions of L...
EXTERN SCIP_RETCODE SCIPlapackComputeIthEigenvalue(BMS_BLKMEM *blkmem, SCIP_Bool geteigenvectors, int n, SCIP_Real *A, int i, SCIP_Real *eigenvalue, SCIP_Real *eigenvector)