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-2022 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 DEFPLUGINS_NLPI
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 separated 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 "scip/nlpi_ipopt.h"
30 #include "blockmemshell/memory.h"
31 
32 /** create solver interface for Ipopt solver and includes it into SCIP, if Ipopt is available */ /*lint -e{715}*/
34  SCIP* scip /**< SCIP data structure */
35  )
36 {
37  return SCIP_OKAY;
38 } /*lint !e715*/
39 
40 /** gets string that identifies Ipopt (version number) */
41 const char* SCIPgetSolverNameIpopt(void)
42 {
43  return "";
44 }
45 
46 /** gets string that describes Ipopt */
47 const char* SCIPgetSolverDescIpopt(void)
48 {
49  return "";
50 }
51 
52 /** returns whether Ipopt is available, i.e., whether it has been linked in */
54 {
55  return FALSE;
56 }
57 
58 /** gives a pointer to the NLPIORACLE object stored in Ipopt-NLPI's NLPI problem data structure */ /*lint -e715*/
60  SCIP_NLPIPROBLEM* nlpiproblem /**< NLP problem of Ipopt-NLPI */
61  )
62 {
63  SCIPerrorMessage("Ipopt not available!\n");
64  SCIPABORT();
65  return NULL; /*lint !e527*/
66 } /*lint !e715*/
67 
68 /** Calls Lapacks Dsyev routine to compute eigenvalues and eigenvectors of a dense matrix.
69  * It's here, because Ipopt is linked against Lapack.
70  */ /*lint -e715*/
72  SCIP_Bool computeeigenvectors,/**< should also eigenvectors should be computed ? */
73  int N, /**< dimension */
74  SCIP_Real* a, /**< matrix data on input (size N*N); eigenvectors on output if computeeigenvectors == TRUE */
75  SCIP_Real* w /**< buffer to store eigenvalues (size N) */
76  )
77 {
78  SCIPerrorMessage("Ipopt not available, cannot use it's Lapack link!\n");
79  return SCIP_ERROR;
80 } /*lint !e715*/
81 
82 /* easier access to the entries of A */
83 #define ENTRY(i,j) (N * (j) + (i))
84 
85 /* solves a linear problem of the form Ax = b for a regular 3*3 matrix A */
86 static
88  SCIP_Real* A, /**< matrix data on input (size 3*3); filled column-wise */
89  SCIP_Real* b, /**< right hand side vector (size 3) */
90  SCIP_Real* x, /**< buffer to store solution (size 3) */
91  SCIP_Bool* success /**< pointer to store if the solving routine was successful */
92  )
93 {
94  SCIP_Real LU[9];
95  SCIP_Real y[3];
96  int pivot[3] = {0, 1, 2};
97  const int N = 3;
98  int k;
99 
100  assert(A != NULL);
101  assert(b != NULL);
102  assert(x != NULL);
103  assert(success != NULL);
104 
105  *success = TRUE;
106 
107  /* copy arrays */
108  BMScopyMemoryArray(LU, A, N*N);
109  BMScopyMemoryArray(y, b, N);
110 
111  /* first step: compute LU factorization */
112  for( k = 0; k < N; ++k )
113  {
114  int p;
115  int i;
116 
117  p = k;
118  for( i = k+1; i < N; ++i )
119  {
120  if( ABS(LU[ ENTRY(pivot[i],k) ]) > ABS( LU[ ENTRY(pivot[p],k) ]) )
121  p = i;
122  }
123 
124  if( ABS(LU[ ENTRY(pivot[p],k) ]) < 1e-08 )
125  {
126  /* SCIPerrorMessage("Error in nlpi_ipopt_dummy - matrix is singular!\n"); */
127  *success = FALSE;
128  return SCIP_OKAY;
129  }
130 
131  if( p != k )
132  {
133  int tmp;
134 
135  tmp = pivot[k];
136  pivot[k] = pivot[p];
137  pivot[p] = tmp;
138  }
139 
140  for( i = k+1; i < N; ++i )
141  {
142  SCIP_Real m;
143  int j;
144 
145  m = LU[ ENTRY(pivot[i],k) ] / LU[ ENTRY(pivot[k],k) ];
146 
147  for( j = k+1; j < N; ++j )
148  LU[ ENTRY(pivot[i],j) ] -= m * LU[ ENTRY(pivot[k],j) ];
149 
150  LU[ ENTRY(pivot[i],k) ] = m;
151  }
152  }
153 
154  /* second step: forward substitution */
155  y[0] = b[pivot[0]];
156 
157  for( k = 1; k < N; ++k )
158  {
159  SCIP_Real s;
160  int j;
161 
162  s = b[pivot[k]];
163  for( j = 0; j < k; ++j )
164  {
165  s -= LU[ ENTRY(pivot[k],j) ] * y[j];
166  }
167  y[k] = s;
168  }
169 
170  /* third step: backward substitution */
171  x[N-1] = y[N-1] / LU[ ENTRY(pivot[N-1],N-1) ];
172  for( k = N-2; k >= 0; --k )
173  {
174  SCIP_Real s;
175  int j;
176 
177  s = y[k];
178  for( j = k+1; j < N; ++j )
179  {
180  s -= LU[ ENTRY(pivot[k],j) ] * x[j];
181  }
182  x[k] = s / LU[ ENTRY(pivot[k],k) ];
183  }
184 
185  return SCIP_OKAY;
186 }
187 
188 /* solves a linear problem of the form Ax = b for a regular matrix A */
190  int N, /**< dimension */
191  SCIP_Real* A, /**< matrix data on input (size N*N); filled column-wise */
192  SCIP_Real* b, /**< right hand side vector (size N) */
193  SCIP_Real* x, /**< buffer to store solution (size N) */
194  SCIP_Bool* success /**< pointer to store if the solving routine was successful */
195  )
196 {
197  SCIP_Real* LU;
198  SCIP_Real* y;
199  int* pivot;
200  int k;
201 
202  SCIP_RETCODE retcode = SCIP_OKAY;
203 
204  assert(N > 0);
205  assert(A != NULL);
206  assert(b != NULL);
207  assert(x != NULL);
208  assert(success != NULL);
209 
210  /* call solveLinearProb3() for performance reasons */
211  if( N == 3 )
212  {
213  SCIP_CALL( solveLinearProb3(A, b, x, success) );
214  return SCIP_OKAY;
215  }
216 
217  *success = TRUE;
218 
219  LU = NULL;
220  y = NULL;
221  pivot = NULL;
222 
223  /* copy arrays */
224  SCIP_ALLOC_TERMINATE( retcode, BMSduplicateMemoryArray(&LU, A, N*N), TERMINATE ); /*lint !e647*/
225  SCIP_ALLOC_TERMINATE( retcode, BMSduplicateMemoryArray(&y, b, N), TERMINATE );
226  SCIP_ALLOC_TERMINATE( retcode, BMSallocMemoryArray(&pivot, N), TERMINATE );
227 
228  /* initialize values */
229  for( k = 0; k < N; ++k )
230  pivot[k] = k;
231 
232  /* first step: compute LU factorization */
233  for( k = 0; k < N; ++k )
234  {
235  int p;
236  int i;
237 
238  p = k;
239  for( i = k+1; i < N; ++i )
240  {
241  if( ABS(LU[ ENTRY(pivot[i],k) ]) > ABS( LU[ ENTRY(pivot[p],k) ]) )
242  p = i;
243  }
244 
245  if( ABS(LU[ ENTRY(pivot[p],k) ]) < 1e-08 )
246  {
247  /* SCIPerrorMessage("Error in nlpi_ipopt_dummy - matrix is singular!\n"); */
248  *success = FALSE;
249  goto TERMINATE;
250  }
251 
252  if( p != k )
253  {
254  int tmp;
255 
256  tmp = pivot[k];
257  pivot[k] = pivot[p];
258  pivot[p] = tmp;
259  }
260 
261  for( i = k+1; i < N; ++i )
262  {
263  SCIP_Real m;
264  int j;
265 
266  m = LU[ ENTRY(pivot[i],k) ] / LU[ ENTRY(pivot[k],k) ];
267 
268  for( j = k+1; j < N; ++j )
269  LU[ ENTRY(pivot[i],j) ] -= m * LU[ ENTRY(pivot[k],j) ];
270 
271  LU[ ENTRY(pivot[i],k) ] = m;
272  }
273  }
274 
275  /* second step: forward substitution */
276  y[0] = b[pivot[0]];
277 
278  for( k = 1; k < N; ++k )
279  {
280  SCIP_Real s;
281  int j;
282 
283  s = b[pivot[k]];
284  for( j = 0; j < k; ++j )
285  {
286  s -= LU[ ENTRY(pivot[k],j) ] * y[j];
287  }
288  y[k] = s;
289  }
290 
291  /* third step: backward substitution */
292  x[N-1] = y[N-1] / LU[ ENTRY(pivot[N-1],N-1) ];
293  for( k = N-2; k >= 0; --k )
294  {
295  SCIP_Real s;
296  int j;
297 
298  s = y[k];
299  for( j = k+1; j < N; ++j )
300  {
301  s -= LU[ ENTRY(pivot[k],j) ] * x[j];
302  }
303  x[k] = s / LU[ ENTRY(pivot[k],k) ];
304  }
305 
306  TERMINATE:
307  /* free arrays */
308  BMSfreeMemoryArrayNull(&pivot);
311 
312  return retcode;
313 }
SCIP_Bool SCIPisIpoptAvailableIpopt(void)
void * SCIPgetNlpiOracleIpopt(SCIP_NLPIPROBLEM *nlpiproblem)
#define ENTRY(i, j)
#define BMSfreeMemoryArrayNull(ptr)
Definition: memory.h:141
SCIP_RETCODE SCIPincludeNlpSolverIpopt(SCIP *scip)
SCIP_RETCODE SCIPcallLapackDsyevIpopt(SCIP_Bool computeeigenvectors, int N, SCIP_Real *a, SCIP_Real *w)
#define FALSE
Definition: def.h:87
#define TRUE
Definition: def.h:86
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
#define BMSallocMemoryArray(ptr, num)
Definition: memory.h:116
SCIP_VAR ** x
Definition: circlepacking.c:54
SCIP_VAR * w
Definition: circlepacking.c:58
const char * SCIPgetSolverNameIpopt(void)
#define SCIPerrorMessage
Definition: pub_message.h:55
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_RETCODE SCIPsolveLinearEquationsIpopt(int N, SCIP_Real *A, SCIP_Real *b, SCIP_Real *x, SCIP_Bool *success)
#define SCIP_CALL(x)
Definition: def.h:384
#define BMSduplicateMemoryArray(ptr, source, num)
Definition: memory.h:136
Ipopt NLP interface.
#define SCIP_Bool
Definition: def.h:84
static SCIP_RETCODE solveLinearProb3(SCIP_Real *A, SCIP_Real *b, SCIP_Real *x, SCIP_Bool *success)
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:127
SCIP_VAR ** b
Definition: circlepacking.c:56
public methods for message output
SCIP_VAR * a
Definition: circlepacking.c:57
const char * SCIPgetSolverDescIpopt(void)
#define SCIP_Real
Definition: def.h:177
SCIP_VAR ** y
Definition: circlepacking.c:55
#define SCIP_ALLOC_TERMINATE(retcode, x, TERM)
Definition: def.h:415
#define SCIPABORT()
Definition: def.h:356
memory allocation routines