Scippy

SCIP

Solving Constraint Integer Programs

nlpi_ipopt_dummy.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2020 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file nlpi_ipopt_dummy.c
17  * @ingroup OTHER_CFILES
18  * @brief dummy Ipopt NLP interface for the case that Ipopt is not available
19  * @author Stefan Vigerske
20  * @author Benjamin Müller
21  *
22  * This code has been separate from nlpi_ipopt.cpp, so the SCIP build system recognizes it as pure C code,
23  * thus the linker does not need to be changed to C++.
24  */
25 
26 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
27 
28 #include "scip/pub_message.h"
29 #include "nlpi/nlpi_ipopt.h"
30 
31 /** create solver interface for Ipopt solver */ /*lint -e715*/
33  BMS_BLKMEM* blkmem, /**< block memory data structure */
34  SCIP_NLPI** nlpi /**< pointer to buffer for nlpi address */
35  )
36 {
37  assert(nlpi != NULL);
38 
39  *nlpi = NULL;
40 
41  return SCIP_OKAY;
42 } /*lint !e715*/
43 
44 /** gets string that identifies Ipopt (version number) */
45 const char* SCIPgetSolverNameIpopt(void)
46 {
47  return "";
48 }
49 
50 /** gets string that describes Ipopt */
51 const char* SCIPgetSolverDescIpopt(void)
52 {
53  return "";
54 }
55 
56 /** returns whether Ipopt is available, i.e., whether it has been linked in */
58 {
59  return FALSE;
60 }
61 
62 /** gives a pointer to the IpoptApplication object stored in Ipopt-NLPI's NLPI problem data structure */ /*lint -e715*/
64  SCIP_NLPIPROBLEM* nlpiproblem /**< NLP problem of Ipopt-NLPI */
65  )
66 {
67  SCIPerrorMessage("Ipopt not available!\n");
68  SCIPABORT();
69  return NULL; /*lint !e527*/
70 } /*lint !e715*/
71 
72 /** gives a pointer to the NLPIORACLE object stored in Ipopt-NLPI's NLPI problem data structure */ /*lint -e715*/
74  SCIP_NLPIPROBLEM* nlpiproblem /**< NLP problem of Ipopt-NLPI */
75  )
76 {
77  SCIPerrorMessage("Ipopt not available!\n");
78  SCIPABORT();
79  return NULL; /*lint !e527*/
80 } /*lint !e715*/
81 
82 /** sets modified default settings that are used when setting up an Ipopt problem
83  *
84  * Do not forget to add a newline after the last option in optionsstring.
85  */ /*lint -e715*/
87  SCIP_NLPI* nlpi, /**< Ipopt NLP interface */
88  const char* optionsstring, /**< string with options as in Ipopt options file */
89  SCIP_Bool append /**< whether to append to modified default settings or to overwrite */
90  )
91 {
92  SCIPerrorMessage("Ipopt not available!\n");
93  SCIPABORT();
94 } /*lint !e715*/
95 
96 /** Calls Lapacks Dsyev routine to compute eigenvalues and eigenvectors of a dense matrix.
97  * It's here, because Ipopt is linked against Lapack.
98  */ /*lint -e715*/
100  SCIP_Bool computeeigenvectors,/**< should also eigenvectors should be computed ? */
101  int N, /**< dimension */
102  SCIP_Real* a, /**< matrix data on input (size N*N); eigenvectors on output if computeeigenvectors == TRUE */
103  SCIP_Real* w /**< buffer to store eigenvalues (size N) */
104  )
105 {
106  SCIPerrorMessage("Ipopt not available, cannot use it's Lapack link!\n");
107  return SCIP_ERROR;
108 } /*lint !e715*/
109 
110 /* easier access to the entries of A */
111 #define ENTRY(i,j) (N * (j) + (i))
112 
113 /* solves a linear problem of the form Ax = b for a regular 3*3 matrix A */
114 static
116  SCIP_Real* A, /**< matrix data on input (size 3*3); filled column-wise */
117  SCIP_Real* b, /**< right hand side vector (size 3) */
118  SCIP_Real* x, /**< buffer to store solution (size 3) */
119  SCIP_Bool* success /**< pointer to store if the solving routine was successful */
120  )
121 {
122  SCIP_Real LU[9];
123  SCIP_Real y[3];
124  int pivot[3] = {0, 1, 2};
125  const int N = 3;
126  int k;
127 
128  assert(A != NULL);
129  assert(b != NULL);
130  assert(x != NULL);
131  assert(success != NULL);
132 
133  *success = TRUE;
134 
135  /* copy arrays */
136  BMScopyMemoryArray(LU, A, N*N);
137  BMScopyMemoryArray(y, b, N);
138 
139  /* first step: compute LU factorization */
140  for( k = 0; k < N; ++k )
141  {
142  int p;
143  int i;
144 
145  p = k;
146  for( i = k+1; i < N; ++i )
147  {
148  if( ABS(LU[ ENTRY(pivot[i],k) ]) > ABS( LU[ ENTRY(pivot[p],k) ]) )
149  p = i;
150  }
151 
152  if( ABS(LU[ ENTRY(pivot[p],k) ]) < 1e-08 )
153  {
154  /* SCIPerrorMessage("Error in nlpi_ipopt_dummy - matrix is singular!\n"); */
155  *success = FALSE;
156  return SCIP_OKAY;
157  }
158 
159  if( p != k )
160  {
161  int tmp;
162 
163  tmp = pivot[k];
164  pivot[k] = pivot[p];
165  pivot[p] = tmp;
166  }
167 
168  for( i = k+1; i < N; ++i )
169  {
170  SCIP_Real m;
171  int j;
172 
173  m = LU[ ENTRY(pivot[i],k) ] / LU[ ENTRY(pivot[k],k) ];
174 
175  for( j = k+1; j < N; ++j )
176  LU[ ENTRY(pivot[i],j) ] -= m * LU[ ENTRY(pivot[k],j) ];
177 
178  LU[ ENTRY(pivot[i],k) ] = m;
179  }
180  }
181 
182  /* second step: forward substitution */
183  y[0] = b[pivot[0]];
184 
185  for( k = 1; k < N; ++k )
186  {
187  SCIP_Real s;
188  int j;
189 
190  s = b[pivot[k]];
191  for( j = 0; j < k; ++j )
192  {
193  s -= LU[ ENTRY(pivot[k],j) ] * y[j];
194  }
195  y[k] = s;
196  }
197 
198  /* third step: backward substitution */
199  x[N-1] = y[N-1] / LU[ ENTRY(pivot[N-1],N-1) ];
200  for( k = N-2; k >= 0; --k )
201  {
202  SCIP_Real s;
203  int j;
204 
205  s = y[k];
206  for( j = k+1; j < N; ++j )
207  {
208  s -= LU[ ENTRY(pivot[k],j) ] * x[j];
209  }
210  x[k] = s / LU[ ENTRY(pivot[k],k) ];
211  }
212 
213  return SCIP_OKAY;
214 }
215 
216 /* solves a linear problem of the form Ax = b for a regular matrix A */
218  int N, /**< dimension */
219  SCIP_Real* A, /**< matrix data on input (size N*N); filled column-wise */
220  SCIP_Real* b, /**< right hand side vector (size N) */
221  SCIP_Real* x, /**< buffer to store solution (size N) */
222  SCIP_Bool* success /**< pointer to store if the solving routine was successful */
223  )
224 {
225  SCIP_Real* LU;
226  SCIP_Real* y;
227  int* pivot;
228  int k;
229 
230  SCIP_RETCODE retcode = SCIP_OKAY;
231 
232  assert(N > 0);
233  assert(A != NULL);
234  assert(b != NULL);
235  assert(x != NULL);
236  assert(success != NULL);
237 
238  /* call SCIPsolveLinearProb3() for performance reasons */
239  if( N == 3 )
240  {
241  SCIP_CALL( SCIPsolveLinearProb3(A, b, x, success) );
242  return SCIP_OKAY;
243  }
244 
245  *success = TRUE;
246 
247  LU = NULL;
248  y = NULL;
249  pivot = NULL;
250 
251  /* copy arrays */
252  SCIP_ALLOC_TERMINATE( retcode, BMSduplicateMemoryArray(&LU, A, N*N), TERMINATE ); /*lint !e647*/
253  SCIP_ALLOC_TERMINATE( retcode, BMSduplicateMemoryArray(&y, b, N), TERMINATE );
254  SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&pivot, N), TERMINATE );
255 
256  /* initialize values */
257  for( k = 0; k < N; ++k )
258  pivot[k] = k;
259 
260  /* first step: compute LU factorization */
261  for( k = 0; k < N; ++k )
262  {
263  int p;
264  int i;
265 
266  p = k;
267  for( i = k+1; i < N; ++i )
268  {
269  if( ABS(LU[ ENTRY(pivot[i],k) ]) > ABS( LU[ ENTRY(pivot[p],k) ]) )
270  p = i;
271  }
272 
273  if( ABS(LU[ ENTRY(pivot[p],k) ]) < 1e-08 )
274  {
275  /* SCIPerrorMessage("Error in nlpi_ipopt_dummy - matrix is singular!\n"); */
276  *success = FALSE;
277  goto TERMINATE;
278  }
279 
280  if( p != k )
281  {
282  int tmp;
283 
284  tmp = pivot[k];
285  pivot[k] = pivot[p];
286  pivot[p] = tmp;
287  }
288 
289  for( i = k+1; i < N; ++i )
290  {
291  SCIP_Real m;
292  int j;
293 
294  m = LU[ ENTRY(pivot[i],k) ] / LU[ ENTRY(pivot[k],k) ];
295 
296  for( j = k+1; j < N; ++j )
297  LU[ ENTRY(pivot[i],j) ] -= m * LU[ ENTRY(pivot[k],j) ];
298 
299  LU[ ENTRY(pivot[i],k) ] = m;
300  }
301  }
302 
303  /* second step: forward substitution */
304  y[0] = b[pivot[0]];
305 
306  for( k = 1; k < N; ++k )
307  {
308  SCIP_Real s;
309  int j;
310 
311  s = b[pivot[k]];
312  for( j = 0; j < k; ++j )
313  {
314  s -= LU[ ENTRY(pivot[k],j) ] * y[j];
315  }
316  y[k] = s;
317  }
318 
319  /* third step: backward substitution */
320  x[N-1] = y[N-1] / LU[ ENTRY(pivot[N-1],N-1) ];
321  for( k = N-2; k >= 0; --k )
322  {
323  SCIP_Real s;
324  int j;
325 
326  s = y[k];
327  for( j = k+1; j < N; ++j )
328  {
329  s -= LU[ ENTRY(pivot[k],j) ] * x[j];
330  }
331  x[k] = s / LU[ ENTRY(pivot[k],k) ];
332  }
333 
334  TERMINATE:
335  /* free arrays */
336  BMSfreeMemoryArrayNull(&pivot);
339 
340  return retcode;
341 }
#define ENTRY(i, j)
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:140
void * SCIPgetNlpiOracleIpopt(SCIP_NLPIPROBLEM *nlpiproblem)
void SCIPsetModifiedDefaultSettingsIpopt(SCIP_NLPI *nlpi, const char *optionsstring, SCIP_Bool append)
#define FALSE
Definition: def.h:73
SCIP_Bool SCIPisIpoptAvailableIpopt(void)
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:115
void * SCIPgetIpoptApplicationPointerIpopt(SCIP_NLPIPROBLEM *nlpiproblem)
SCIP_VAR ** x
Definition: circlepacking.c:54
SCIP_VAR * w
Definition: circlepacking.c:58
SCIP_RETCODE LapackDsyev(SCIP_Bool computeeigenvectors, int N, SCIP_Real *a, SCIP_Real *w)
#define SCIPerrorMessage
Definition: pub_message.h:55
const char * SCIPgetSolverDescIpopt(void)
#define NULL
Definition: lpi_spx1.cpp:155
#define SCIP_CALL(x)
Definition: def.h:364
const char * SCIPgetSolverNameIpopt(void)
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:135
Ipopt NLP interface.
static SCIP_RETCODE SCIPsolveLinearProb3(SCIP_Real *A, SCIP_Real *b, SCIP_Real *x, SCIP_Bool *success)
#define SCIP_Bool
Definition: def.h:70
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:126
SCIP_VAR ** b
Definition: circlepacking.c:56
SCIP_RETCODE SCIPsolveLinearProb(int N, SCIP_Real *A, SCIP_Real *b, SCIP_Real *x, SCIP_Bool *success)
public methods for message output
SCIP_VAR * a
Definition: circlepacking.c:57
#define SCIP_Real
Definition: def.h:163
SCIP_VAR ** y
Definition: circlepacking.c:55
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:429
#define SCIP_ALLOC_TERMINATE(retcode, x, TERM)
Definition: def.h:395
#define SCIPABORT()
Definition: def.h:336
SCIP_RETCODE SCIPcreateNlpSolverIpopt(BMS_BLKMEM *blkmem, SCIP_NLPI **nlpi)