SCIP-SDP  2.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
lapack_dsdp.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-2016 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-2016 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 
56 #define BMS_CALL(x) do \
57  { \
58  if( NULL == (x) ) \
59  { \
60  SCIPerrorMessage("No memory in function call\n"); \
61  return SCIP_NOMEMORY; \
62  } \
63  } \
64  while( FALSE )
65 
67 #define SCIP_RealTOINT(x) ((int) (x + 0.5))
68 
69 /*
70  * BLAS/LAPACK Calls
71  */
72 
77 void F77_FUNC(dsyevr, DSYEVR)(
78  char* JOBZ, char* RANGE, char* UPLO,
79  int* N, SCIP_Real* A, int* LDA,
80  SCIP_Real* VL, SCIP_Real* VU,
81  int* IL, int* IU,
82  SCIP_Real* ABSTOL, int* M, SCIP_Real* W, SCIP_Real* Z,
83  int* LDZ, int* ISUPPZ, SCIP_Real* WORK,
84  int* LWORK, int* IWORK, int* LIWORK,
85  int* INFO );
86 
87 
89 void F77_FUNC(dgemv, DGEMV)(char* TRANS, int* M, int* N, SCIP_Real* ALPHA, SCIP_Real* A, int* LDA, SCIP_Real* X, int* INCX, SCIP_Real* BETA, SCIP_Real* Y, int* INCY);
90 
91 
95 /*
96  * Functions
97  */
98 
103 SCIP_RETCODE SCIPlapackComputeIthEigenvalue(
104  BMS_BLKMEM* blkmem,
105  SCIP_Bool geteigenvectors,
106  int n,
107  SCIP_Real* A,
108  int i,
109  SCIP_Real* eigenvalue,
110  SCIP_Real* eigenvector
111  )
112 {
113  int N;
114  int INFO;
115  char JOBZ;
116  char RANGE;
117  char UPLO;
118  int LDA;
119  SCIP_Real* WORK;
120  int LWORK;
121  int* IWORK;
122  int LIWORK;
123  SCIP_Real* WTMP;
124  SCIP_Real ABSTOL;
125  int IL;
126  int IU;
127  int M;
128  int LDZ;
129  SCIP_Real WSIZE;
130  int WISIZE;
131  SCIP_Real VL;
132  SCIP_Real VU;
133  int* ISUPPZ;
134 
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 = -1;
156  LIWORK = -1;
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 = SCIP_RealTOINT(WSIZE);
176  LIWORK = WISIZE;
177 
178  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &WORK, LWORK) );
179  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &IWORK, LIWORK) );
180  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &WTMP, N) );
181  BMS_CALL( BMSallocBlockMemoryArray(blkmem, &ISUPPZ, 2) );
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, N);/*lint !e737*/
208  BMSfreeBlockMemoryArray(blkmem, &IWORK, LIWORK);/*lint !e737*/
209  BMSfreeBlockMemoryArray(blkmem, &WORK, LWORK);/*lint !e737*/
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  int M;
225  int N;
226  SCIP_Real ALPHA;
227  SCIP_Real* A;
228  int LDA;
229  SCIP_Real* X;
230  int INCX;
231  SCIP_Real BETA;
232  SCIP_Real* Y;
233  int 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 
Macros for calling Fortran-functions.
SCIP_RETCODE SCIPlapackMatrixVectorMult(int nrows, int ncols, SCIP_Real *matrix, SCIP_Real *vector, SCIP_Real *result)
Definition: lapack_dsdp.c:215
#define BMS_CALL(x)
Definition: lapack_dsdp.c:56
#define F77_FUNC(name, NAME)
Definition: config.h:43
interface methods for eigenvector computation and matrix multiplication using different versions of L...
#define SCIP_RealTOINT(x)
Definition: lapack_dsdp.c:67
EXTERN SCIP_RETCODE SCIPlapackComputeIthEigenvalue(BMS_BLKMEM *blkmem, SCIP_Bool geteigenvectors, int n, SCIP_Real *A, int i, SCIP_Real *eigenvalue, SCIP_Real *eigenvector)