Mercurial > octave-nkf
comparison libinterp/dldfcn/__glpk__.cc @ 15195:2fc554ffbc28
split libinterp from src
* libinterp: New directory. Move all files from src directory here
except Makefile.am, main.cc, main-cli.cc, mkoctfile.in.cc,
mkoctfilr.in.sh, octave-config.in.cc, octave-config.in.sh.
* libinterp/Makefile.am: New file, extracted from src/Makefile.am.
* src/Makefile.am: Delete everything except targets and definitions
needed to build and link main and utility programs.
* Makefile.am (SUBDIRS): Include libinterp in the list.
* autogen.sh: Run config-module.sh in libinterp/dldfcn directory, not
src/dldfcn directory.
* configure.ac (AC_CONFIG_SRCDIR): Use libinterp/octave.cc, not
src/octave.cc.
(DL_LDFLAGS, LIBOCTINTERP): Use libinterp, not src.
(AC_CONFIG_FILES): Include libinterp/Makefile in the list.
* find-docstring-files.sh: Look in libinterp, not src.
* gui/src/Makefile.am (liboctgui_la_CPPFLAGS): Find header files in
libinterp, not src.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 18 Aug 2012 16:23:39 -0400 |
parents | src/dldfcn/__glpk__.cc@000587f92082 |
children | 336f42406671 |
comparison
equal
deleted
inserted
replaced
15194:0f0b795044c3 | 15195:2fc554ffbc28 |
---|---|
1 /* | |
2 | |
3 Copyright (C) 2005-2012 Nicolo' Giorgetti | |
4 | |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 3 of the License, or (at your | |
10 option) any later version. | |
11 | |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with Octave; see the file COPYING. If not, see | |
19 <http://www.gnu.org/licenses/>. | |
20 | |
21 */ | |
22 | |
23 #ifdef HAVE_CONFIG_H | |
24 #include <config.h> | |
25 #endif | |
26 | |
27 #include <cfloat> | |
28 #include <csetjmp> | |
29 #include <ctime> | |
30 | |
31 #include "lo-ieee.h" | |
32 | |
33 #include "defun-dld.h" | |
34 #include "error.h" | |
35 #include "gripes.h" | |
36 #include "oct-map.h" | |
37 #include "oct-obj.h" | |
38 #include "pager.h" | |
39 | |
40 #if defined (HAVE_GLPK) | |
41 | |
42 extern "C" | |
43 { | |
44 #if defined (HAVE_GLPK_GLPK_H) | |
45 #include <glpk/glpk.h> | |
46 #else | |
47 #include <glpk.h> | |
48 #endif | |
49 | |
50 #if 0 | |
51 #ifdef GLPK_PRE_4_14 | |
52 | |
53 #ifndef _GLPLIB_H | |
54 #include <glplib.h> | |
55 #endif | |
56 #ifndef lib_set_fault_hook | |
57 #define lib_set_fault_hook lib_fault_hook | |
58 #endif | |
59 #ifndef lib_set_print_hook | |
60 #define lib_set_print_hook lib_print_hook | |
61 #endif | |
62 | |
63 #else | |
64 | |
65 void _glp_lib_print_hook (int (*func)(void *info, char *buf), void *info); | |
66 void _glp_lib_fault_hook (int (*func)(void *info, char *buf), void *info); | |
67 | |
68 #endif | |
69 #endif | |
70 } | |
71 | |
72 #define NIntP 17 | |
73 #define NRealP 10 | |
74 | |
75 int lpxIntParam[NIntP] = { | |
76 0, | |
77 1, | |
78 0, | |
79 1, | |
80 0, | |
81 -1, | |
82 0, | |
83 200, | |
84 1, | |
85 2, | |
86 0, | |
87 1, | |
88 0, | |
89 0, | |
90 2, | |
91 2, | |
92 1 | |
93 }; | |
94 | |
95 int IParam[NIntP] = { | |
96 LPX_K_MSGLEV, | |
97 LPX_K_SCALE, | |
98 LPX_K_DUAL, | |
99 LPX_K_PRICE, | |
100 LPX_K_ROUND, | |
101 LPX_K_ITLIM, | |
102 LPX_K_ITCNT, | |
103 LPX_K_OUTFRQ, | |
104 LPX_K_MPSINFO, | |
105 LPX_K_MPSOBJ, | |
106 LPX_K_MPSORIG, | |
107 LPX_K_MPSWIDE, | |
108 LPX_K_MPSFREE, | |
109 LPX_K_MPSSKIP, | |
110 LPX_K_BRANCH, | |
111 LPX_K_BTRACK, | |
112 LPX_K_PRESOL | |
113 }; | |
114 | |
115 | |
116 double lpxRealParam[NRealP] = { | |
117 0.07, | |
118 1e-7, | |
119 1e-7, | |
120 1e-9, | |
121 -DBL_MAX, | |
122 DBL_MAX, | |
123 -1.0, | |
124 0.0, | |
125 1e-6, | |
126 1e-7 | |
127 }; | |
128 | |
129 int RParam[NRealP] = { | |
130 LPX_K_RELAX, | |
131 LPX_K_TOLBND, | |
132 LPX_K_TOLDJ, | |
133 LPX_K_TOLPIV, | |
134 LPX_K_OBJLL, | |
135 LPX_K_OBJUL, | |
136 LPX_K_TMLIM, | |
137 LPX_K_OUTDLY, | |
138 LPX_K_TOLINT, | |
139 LPX_K_TOLOBJ | |
140 }; | |
141 | |
142 static jmp_buf mark; //-- Address for long jump to jump to | |
143 | |
144 #if 0 | |
145 int | |
146 glpk_fault_hook (void * /* info */, char *msg) | |
147 { | |
148 error ("CRITICAL ERROR in GLPK: %s", msg); | |
149 longjmp (mark, -1); | |
150 } | |
151 | |
152 int | |
153 glpk_print_hook (void * /* info */, char *msg) | |
154 { | |
155 message (0, "%s", msg); | |
156 return 1; | |
157 } | |
158 #endif | |
159 | |
160 int | |
161 glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn, | |
162 double *a, double *b, char *ctype, int *freeLB, double *lb, | |
163 int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, | |
164 int save_pb, double *xmin, double *fmin, double *status, | |
165 double *lambda, double *redcosts, double *time, double *mem) | |
166 { | |
167 int errnum; | |
168 int typx = 0; | |
169 int method; | |
170 | |
171 clock_t t_start = clock (); | |
172 | |
173 #if 0 | |
174 #ifdef GLPK_PRE_4_14 | |
175 lib_set_fault_hook (0, glpk_fault_hook); | |
176 #else | |
177 _glp_lib_fault_hook (glpk_fault_hook, 0); | |
178 #endif | |
179 | |
180 if (lpxIntParam[0] > 1) | |
181 #ifdef GLPK_PRE_4_14 | |
182 lib_set_print_hook (0, glpk_print_hook); | |
183 #else | |
184 _glp_lib_print_hook (glpk_print_hook, 0); | |
185 #endif | |
186 #endif | |
187 | |
188 LPX *lp = lpx_create_prob (); | |
189 | |
190 | |
191 //-- Set the sense of optimization | |
192 if (sense == 1) | |
193 lpx_set_obj_dir (lp, LPX_MIN); | |
194 else | |
195 lpx_set_obj_dir (lp, LPX_MAX); | |
196 | |
197 //-- If the problem has integer structural variables switch to MIP | |
198 if (isMIP) | |
199 lpx_set_class (lp, LPX_MIP); | |
200 | |
201 lpx_add_cols (lp, n); | |
202 for (int i = 0; i < n; i++) | |
203 { | |
204 //-- Define type of the structural variables | |
205 if (! freeLB[i] && ! freeUB[i]) | |
206 { | |
207 if (lb[i] != ub[i]) | |
208 lpx_set_col_bnds (lp, i+1, LPX_DB, lb[i], ub[i]); | |
209 else | |
210 lpx_set_col_bnds (lp, i+1, LPX_FX, lb[i], ub[i]); | |
211 } | |
212 else | |
213 { | |
214 if (! freeLB[i] && freeUB[i]) | |
215 lpx_set_col_bnds (lp, i+1, LPX_LO, lb[i], ub[i]); | |
216 else | |
217 { | |
218 if (freeLB[i] && ! freeUB[i]) | |
219 lpx_set_col_bnds (lp, i+1, LPX_UP, lb[i], ub[i]); | |
220 else | |
221 lpx_set_col_bnds (lp, i+1, LPX_FR, lb[i], ub[i]); | |
222 } | |
223 } | |
224 | |
225 // -- Set the objective coefficient of the corresponding | |
226 // -- structural variable. No constant term is assumed. | |
227 lpx_set_obj_coef(lp,i+1,c[i]); | |
228 | |
229 if (isMIP) | |
230 lpx_set_col_kind (lp, i+1, vartype[i]); | |
231 } | |
232 | |
233 lpx_add_rows (lp, m); | |
234 | |
235 for (int i = 0; i < m; i++) | |
236 { | |
237 /* If the i-th row has no lower bound (types F,U), the | |
238 corrispondent parameter will be ignored. | |
239 If the i-th row has no upper bound (types F,L), the corrispondent | |
240 parameter will be ignored. | |
241 If the i-th row is of S type, the i-th LB is used, but | |
242 the i-th UB is ignored. | |
243 */ | |
244 | |
245 switch (ctype[i]) | |
246 { | |
247 case 'F': | |
248 typx = LPX_FR; | |
249 break; | |
250 | |
251 case 'U': | |
252 typx = LPX_UP; | |
253 break; | |
254 | |
255 case 'L': | |
256 typx = LPX_LO; | |
257 break; | |
258 | |
259 case 'S': | |
260 typx = LPX_FX; | |
261 break; | |
262 | |
263 case 'D': | |
264 typx = LPX_DB; | |
265 break; | |
266 } | |
267 | |
268 lpx_set_row_bnds (lp, i+1, typx, b[i], b[i]); | |
269 | |
270 } | |
271 | |
272 lpx_load_matrix (lp, nz, rn, cn, a); | |
273 | |
274 if (save_pb) | |
275 { | |
276 static char tmp[] = "outpb.lp"; | |
277 if (lpx_write_cpxlp (lp, tmp) != 0) | |
278 { | |
279 error ("__glpk__: unable to write problem"); | |
280 longjmp (mark, -1); | |
281 } | |
282 } | |
283 | |
284 //-- scale the problem data (if required) | |
285 //-- if (scale && (!presol || method == 1)) lpx_scale_prob (lp); | |
286 //-- LPX_K_SCALE=IParam[1] LPX_K_PRESOL=IParam[16] | |
287 if (lpxIntParam[1] && (! lpxIntParam[16] || lpsolver != 1)) | |
288 lpx_scale_prob (lp); | |
289 | |
290 //-- build advanced initial basis (if required) | |
291 if (lpsolver == 1 && ! lpxIntParam[16]) | |
292 lpx_adv_basis (lp); | |
293 | |
294 for (int i = 0; i < NIntP; i++) | |
295 lpx_set_int_parm (lp, IParam[i], lpxIntParam[i]); | |
296 | |
297 for (int i = 0; i < NRealP; i++) | |
298 lpx_set_real_parm (lp, RParam[i], lpxRealParam[i]); | |
299 | |
300 if (lpsolver == 1) | |
301 method = 'S'; | |
302 else | |
303 method = 'T'; | |
304 | |
305 switch (method) | |
306 { | |
307 case 'S': | |
308 { | |
309 if (isMIP) | |
310 { | |
311 method = 'I'; | |
312 errnum = lpx_simplex (lp); | |
313 errnum = lpx_integer (lp); | |
314 } | |
315 else | |
316 errnum = lpx_simplex (lp); | |
317 } | |
318 break; | |
319 | |
320 case 'T': | |
321 errnum = lpx_interior (lp); | |
322 break; | |
323 | |
324 default: | |
325 break; | |
326 #if 0 | |
327 #ifdef GLPK_PRE_4_14 | |
328 insist (method != method); | |
329 #else | |
330 static char tmp[] = "method != method"; | |
331 glpk_fault_hook (0, tmp); | |
332 #endif | |
333 #endif | |
334 } | |
335 | |
336 /* errnum assumes the following results: | |
337 errnum = 0 <=> No errors | |
338 errnum = 1 <=> Iteration limit exceeded. | |
339 errnum = 2 <=> Numerical problems with basis matrix. | |
340 */ | |
341 if (errnum == LPX_E_OK) | |
342 { | |
343 if (isMIP) | |
344 { | |
345 *status = lpx_mip_status (lp); | |
346 *fmin = lpx_mip_obj_val (lp); | |
347 } | |
348 else | |
349 { | |
350 if (lpsolver == 1) | |
351 { | |
352 *status = lpx_get_status (lp); | |
353 *fmin = lpx_get_obj_val (lp); | |
354 } | |
355 else | |
356 { | |
357 *status = lpx_ipt_status (lp); | |
358 *fmin = lpx_ipt_obj_val (lp); | |
359 } | |
360 } | |
361 | |
362 if (isMIP) | |
363 { | |
364 for (int i = 0; i < n; i++) | |
365 xmin[i] = lpx_mip_col_val (lp, i+1); | |
366 } | |
367 else | |
368 { | |
369 /* Primal values */ | |
370 for (int i = 0; i < n; i++) | |
371 { | |
372 if (lpsolver == 1) | |
373 xmin[i] = lpx_get_col_prim (lp, i+1); | |
374 else | |
375 xmin[i] = lpx_ipt_col_prim (lp, i+1); | |
376 } | |
377 | |
378 /* Dual values */ | |
379 for (int i = 0; i < m; i++) | |
380 { | |
381 if (lpsolver == 1) | |
382 lambda[i] = lpx_get_row_dual (lp, i+1); | |
383 else | |
384 lambda[i] = lpx_ipt_row_dual (lp, i+1); | |
385 } | |
386 | |
387 /* Reduced costs */ | |
388 for (int i = 0; i < lpx_get_num_cols (lp); i++) | |
389 { | |
390 if (lpsolver == 1) | |
391 redcosts[i] = lpx_get_col_dual (lp, i+1); | |
392 else | |
393 redcosts[i] = lpx_ipt_col_dual (lp, i+1); | |
394 } | |
395 } | |
396 | |
397 *time = (clock () - t_start) / CLOCKS_PER_SEC; | |
398 | |
399 #ifdef GLPK_PRE_4_14 | |
400 *mem = (lib_env_ptr () -> mem_tpeak); | |
401 #else | |
402 *mem = 0; | |
403 #endif | |
404 | |
405 lpx_delete_prob (lp); | |
406 return 0; | |
407 } | |
408 | |
409 lpx_delete_prob (lp); | |
410 | |
411 *status = errnum; | |
412 | |
413 return errnum; | |
414 } | |
415 | |
416 #endif | |
417 | |
418 #define OCTAVE_GLPK_GET_REAL_PARAM(NAME, IDX) \ | |
419 do \ | |
420 { \ | |
421 octave_value tmp = PARAM.getfield (NAME); \ | |
422 \ | |
423 if (tmp.is_defined ()) \ | |
424 { \ | |
425 if (! tmp.is_empty ()) \ | |
426 { \ | |
427 lpxRealParam[IDX] = tmp.scalar_value (); \ | |
428 \ | |
429 if (error_state) \ | |
430 { \ | |
431 error ("glpk: invalid value in PARAM." NAME); \ | |
432 return retval; \ | |
433 } \ | |
434 } \ | |
435 else \ | |
436 { \ | |
437 error ("glpk: invalid value in PARAM." NAME); \ | |
438 return retval; \ | |
439 } \ | |
440 } \ | |
441 } \ | |
442 while (0) | |
443 | |
444 #define OCTAVE_GLPK_GET_INT_PARAM(NAME, VAL) \ | |
445 do \ | |
446 { \ | |
447 octave_value tmp = PARAM.getfield (NAME); \ | |
448 \ | |
449 if (tmp.is_defined ()) \ | |
450 { \ | |
451 if (! tmp.is_empty ()) \ | |
452 { \ | |
453 VAL = tmp.int_value (); \ | |
454 \ | |
455 if (error_state) \ | |
456 { \ | |
457 error ("glpk: invalid value in PARAM." NAME); \ | |
458 return retval; \ | |
459 } \ | |
460 } \ | |
461 else \ | |
462 { \ | |
463 error ("glpk: invalid value in PARAM." NAME); \ | |
464 return retval; \ | |
465 } \ | |
466 } \ | |
467 } \ | |
468 while (0) | |
469 | |
470 DEFUN_DLD (__glpk__, args, , | |
471 "-*- texinfo -*-\n\ | |
472 @deftypefn {Loadable Function} {[@var{values}] =} __glpk__ (@var{args})\n\ | |
473 Undocumented internal function.\n\ | |
474 @end deftypefn") | |
475 { | |
476 // The list of values to return. See the declaration in oct-obj.h | |
477 octave_value_list retval; | |
478 | |
479 #if defined (HAVE_GLPK) | |
480 | |
481 int nrhs = args.length (); | |
482 | |
483 if (nrhs != 9) | |
484 { | |
485 print_usage (); | |
486 return retval; | |
487 } | |
488 | |
489 //-- 1nd Input. A column array containing the objective function | |
490 //-- coefficients. | |
491 volatile int mrowsc = args(0).rows (); | |
492 | |
493 Matrix C (args(0).matrix_value ()); | |
494 | |
495 if (error_state) | |
496 { | |
497 error ("__glpk__: invalid value of C"); | |
498 return retval; | |
499 } | |
500 | |
501 double *c = C.fortran_vec (); | |
502 Array<int> rn; | |
503 Array<int> cn; | |
504 ColumnVector a; | |
505 volatile int mrowsA; | |
506 volatile int nz = 0; | |
507 | |
508 //-- 2nd Input. A matrix containing the constraints coefficients. | |
509 // If matrix A is NOT a sparse matrix | |
510 if (args(1).is_sparse_type ()) | |
511 { | |
512 SparseMatrix A = args(1).sparse_matrix_value (); // get the sparse matrix | |
513 | |
514 if (error_state) | |
515 { | |
516 error ("__glpk__: invalid value of A"); | |
517 return retval; | |
518 } | |
519 | |
520 mrowsA = A.rows (); | |
521 octave_idx_type Anc = A.cols (); | |
522 octave_idx_type Anz = A.nnz (); | |
523 rn.resize (dim_vector (Anz+1, 1)); | |
524 cn.resize (dim_vector (Anz+1, 1)); | |
525 a.resize (Anz+1, 0.0); | |
526 | |
527 if (Anc != mrowsc) | |
528 { | |
529 error ("__glpk__: invalid value of A"); | |
530 return retval; | |
531 } | |
532 | |
533 for (octave_idx_type j = 0; j < Anc; j++) | |
534 for (octave_idx_type i = A.cidx (j); i < A.cidx (j+1); i++) | |
535 { | |
536 nz++; | |
537 rn(nz) = A.ridx (i) + 1; | |
538 cn(nz) = j + 1; | |
539 a(nz) = A.data(i); | |
540 } | |
541 } | |
542 else | |
543 { | |
544 Matrix A (args(1).matrix_value ()); // get the matrix | |
545 | |
546 if (error_state) | |
547 { | |
548 error ("__glpk__: invalid value of A"); | |
549 return retval; | |
550 } | |
551 | |
552 mrowsA = A.rows (); | |
553 rn.resize (dim_vector (mrowsA*mrowsc+1, 1)); | |
554 cn.resize (dim_vector (mrowsA*mrowsc+1, 1)); | |
555 a.resize (mrowsA*mrowsc+1, 0.0); | |
556 | |
557 for (int i = 0; i < mrowsA; i++) | |
558 { | |
559 for (int j = 0; j < mrowsc; j++) | |
560 { | |
561 if (A(i,j) != 0) | |
562 { | |
563 nz++; | |
564 rn(nz) = i + 1; | |
565 cn(nz) = j + 1; | |
566 a(nz) = A(i,j); | |
567 } | |
568 } | |
569 } | |
570 | |
571 } | |
572 | |
573 //-- 3rd Input. A column array containing the right-hand side value | |
574 // for each constraint in the constraint matrix. | |
575 Matrix B (args(2).matrix_value ()); | |
576 | |
577 if (error_state) | |
578 { | |
579 error ("__glpk__: invalid value of B"); | |
580 return retval; | |
581 } | |
582 | |
583 double *b = B.fortran_vec (); | |
584 | |
585 //-- 4th Input. An array of length mrowsc containing the lower | |
586 //-- bound on each of the variables. | |
587 Matrix LB (args(3).matrix_value ()); | |
588 | |
589 if (error_state || LB.length () < mrowsc) | |
590 { | |
591 error ("__glpk__: invalid value of LB"); | |
592 return retval; | |
593 } | |
594 | |
595 double *lb = LB.fortran_vec (); | |
596 | |
597 //-- LB argument, default: Free | |
598 Array<int> freeLB (dim_vector (mrowsc, 1)); | |
599 for (int i = 0; i < mrowsc; i++) | |
600 { | |
601 if (xisinf (lb[i])) | |
602 { | |
603 freeLB(i) = 1; | |
604 lb[i] = -octave_Inf; | |
605 } | |
606 else | |
607 freeLB(i) = 0; | |
608 } | |
609 | |
610 //-- 5th Input. An array of at least length numcols containing the upper | |
611 //-- bound on each of the variables. | |
612 Matrix UB (args(4).matrix_value ()); | |
613 | |
614 if (error_state || UB.length () < mrowsc) | |
615 { | |
616 error ("__glpk__: invalid value of UB"); | |
617 return retval; | |
618 } | |
619 | |
620 double *ub = UB.fortran_vec (); | |
621 | |
622 Array<int> freeUB (dim_vector (mrowsc, 1)); | |
623 for (int i = 0; i < mrowsc; i++) | |
624 { | |
625 if (xisinf (ub[i])) | |
626 { | |
627 freeUB(i) = 1; | |
628 ub[i] = octave_Inf; | |
629 } | |
630 else | |
631 freeUB(i) = 0; | |
632 } | |
633 | |
634 //-- 6th Input. A column array containing the sense of each constraint | |
635 //-- in the constraint matrix. | |
636 charMatrix CTYPE (args(5).char_matrix_value ()); | |
637 | |
638 if (error_state) | |
639 { | |
640 error ("__glpk__: invalid value of CTYPE"); | |
641 return retval; | |
642 } | |
643 | |
644 char *ctype = CTYPE.fortran_vec (); | |
645 | |
646 //-- 7th Input. A column array containing the types of the variables. | |
647 charMatrix VTYPE (args(6).char_matrix_value ()); | |
648 | |
649 if (error_state) | |
650 { | |
651 error ("__glpk__: invalid value of VARTYPE"); | |
652 return retval; | |
653 } | |
654 | |
655 Array<int> vartype (dim_vector (mrowsc, 1)); | |
656 volatile int isMIP = 0; | |
657 for (int i = 0; i < mrowsc ; i++) | |
658 { | |
659 if (VTYPE(i,0) == 'I') | |
660 { | |
661 isMIP = 1; | |
662 vartype(i) = LPX_IV; | |
663 } | |
664 else | |
665 vartype(i) = LPX_CV; | |
666 } | |
667 | |
668 //-- 8th Input. Sense of optimization. | |
669 volatile int sense; | |
670 double SENSE = args(7).scalar_value (); | |
671 | |
672 if (error_state) | |
673 { | |
674 error ("__glpk__: invalid value of SENSE"); | |
675 return retval; | |
676 } | |
677 | |
678 if (SENSE >= 0) | |
679 sense = 1; | |
680 else | |
681 sense = -1; | |
682 | |
683 //-- 9th Input. A structure containing the control parameters. | |
684 octave_scalar_map PARAM = args(8).scalar_map_value (); | |
685 | |
686 if (error_state) | |
687 { | |
688 error ("__glpk__: invalid value of PARAM"); | |
689 return retval; | |
690 } | |
691 | |
692 //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
693 //-- Integer parameters | |
694 //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
695 | |
696 //-- Level of messages output by the solver | |
697 OCTAVE_GLPK_GET_INT_PARAM ("msglev", lpxIntParam[0]); | |
698 if (lpxIntParam[0] < 0 || lpxIntParam[0] > 3) | |
699 { | |
700 error ("__glpk__: PARAM.msglev must be 0 (no output [default]) or 1 (error messages only) or 2 (normal output) or 3 (full output)"); | |
701 return retval; | |
702 } | |
703 | |
704 //-- scaling option | |
705 OCTAVE_GLPK_GET_INT_PARAM ("scale", lpxIntParam[1]); | |
706 if (lpxIntParam[1] < 0 || lpxIntParam[1] > 2) | |
707 { | |
708 error ("__glpk__: PARAM.scale must be 0 (no scaling) or 1 (equilibration scaling [default]) or 2 (geometric mean scaling)"); | |
709 return retval; | |
710 } | |
711 | |
712 //-- Dual dimplex option | |
713 OCTAVE_GLPK_GET_INT_PARAM ("dual", lpxIntParam[2]); | |
714 if (lpxIntParam[2] < 0 || lpxIntParam[2] > 1) | |
715 { | |
716 error ("__glpk__: PARAM.dual must be 0 (do NOT use dual simplex [default]) or 1 (use dual simplex)"); | |
717 return retval; | |
718 } | |
719 | |
720 //-- Pricing option | |
721 OCTAVE_GLPK_GET_INT_PARAM ("price", lpxIntParam[3]); | |
722 if (lpxIntParam[3] < 0 || lpxIntParam[3] > 1) | |
723 { | |
724 error ("__glpk__: PARAM.price must be 0 (textbook pricing) or 1 (steepest edge pricing [default])"); | |
725 return retval; | |
726 } | |
727 | |
728 //-- Solution rounding option | |
729 OCTAVE_GLPK_GET_INT_PARAM ("round", lpxIntParam[4]); | |
730 if (lpxIntParam[4] < 0 || lpxIntParam[4] > 1) | |
731 { | |
732 error ("__glpk__: PARAM.round must be 0 (report all primal and dual values [default]) or 1 (replace tiny primal and dual values by exact zero)"); | |
733 return retval; | |
734 } | |
735 | |
736 //-- Simplex iterations limit | |
737 OCTAVE_GLPK_GET_INT_PARAM ("itlim", lpxIntParam[5]); | |
738 | |
739 //-- Simplex iterations count | |
740 OCTAVE_GLPK_GET_INT_PARAM ("itcnt", lpxIntParam[6]); | |
741 | |
742 //-- Output frequency, in iterations | |
743 OCTAVE_GLPK_GET_INT_PARAM ("outfrq", lpxIntParam[7]); | |
744 | |
745 //-- Branching heuristic option | |
746 OCTAVE_GLPK_GET_INT_PARAM ("branch", lpxIntParam[14]); | |
747 if (lpxIntParam[14] < 0 || lpxIntParam[14] > 2) | |
748 { | |
749 error ("__glpk__: PARAM.branch must be (MIP only) 0 (branch on first variable) or 1 (branch on last variable) or 2 (branch using a heuristic by Driebeck and Tomlin [default]"); | |
750 return retval; | |
751 } | |
752 | |
753 //-- Backtracking heuristic option | |
754 OCTAVE_GLPK_GET_INT_PARAM ("btrack", lpxIntParam[15]); | |
755 if (lpxIntParam[15] < 0 || lpxIntParam[15] > 2) | |
756 { | |
757 error ("__glpk__: PARAM.btrack must be (MIP only) 0 (depth first search) or 1 (breadth first search) or 2 (backtrack using the best projection heuristic [default]"); | |
758 return retval; | |
759 } | |
760 | |
761 //-- Presolver option | |
762 OCTAVE_GLPK_GET_INT_PARAM ("presol", lpxIntParam[16]); | |
763 if (lpxIntParam[16] < 0 || lpxIntParam[16] > 1) | |
764 { | |
765 error ("__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])"); | |
766 return retval; | |
767 } | |
768 | |
769 //-- LPsolver option | |
770 volatile int lpsolver = 1; | |
771 OCTAVE_GLPK_GET_INT_PARAM ("lpsolver", lpsolver); | |
772 if (lpsolver < 1 || lpsolver > 2) | |
773 { | |
774 error ("__glpk__: PARAM.lpsolver must be 1 (simplex method) or 2 (interior point method)"); | |
775 return retval; | |
776 } | |
777 | |
778 //-- Save option | |
779 volatile int save_pb = 0; | |
780 OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb); | |
781 save_pb = save_pb != 0; | |
782 | |
783 //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
784 //-- Real parameters | |
785 //-- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
786 | |
787 //-- Ratio test option | |
788 OCTAVE_GLPK_GET_REAL_PARAM ("relax", 0); | |
789 | |
790 //-- Relative tolerance used to check if the current basic solution | |
791 //-- is primal feasible | |
792 OCTAVE_GLPK_GET_REAL_PARAM ("tolbnd", 1); | |
793 | |
794 //-- Absolute tolerance used to check if the current basic solution | |
795 //-- is dual feasible | |
796 OCTAVE_GLPK_GET_REAL_PARAM ("toldj", 2); | |
797 | |
798 //-- Relative tolerance used to choose eligible pivotal elements of | |
799 //-- the simplex table in the ratio test | |
800 OCTAVE_GLPK_GET_REAL_PARAM ("tolpiv", 3); | |
801 | |
802 OCTAVE_GLPK_GET_REAL_PARAM ("objll", 4); | |
803 | |
804 OCTAVE_GLPK_GET_REAL_PARAM ("objul", 5); | |
805 | |
806 OCTAVE_GLPK_GET_REAL_PARAM ("tmlim", 6); | |
807 | |
808 OCTAVE_GLPK_GET_REAL_PARAM ("outdly", 7); | |
809 | |
810 OCTAVE_GLPK_GET_REAL_PARAM ("tolint", 8); | |
811 | |
812 OCTAVE_GLPK_GET_REAL_PARAM ("tolobj", 9); | |
813 | |
814 //-- Assign pointers to the output parameters | |
815 ColumnVector xmin (mrowsc, octave_NA); | |
816 double fmin = octave_NA; | |
817 double status; | |
818 ColumnVector lambda (mrowsA, octave_NA); | |
819 ColumnVector redcosts (mrowsc, octave_NA); | |
820 double time; | |
821 double mem; | |
822 | |
823 int jmpret = setjmp (mark); | |
824 | |
825 if (jmpret == 0) | |
826 glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (), | |
827 cn.fortran_vec (), a.fortran_vec (), b, ctype, | |
828 freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub, | |
829 vartype.fortran_vec (), isMIP, lpsolver, save_pb, | |
830 xmin.fortran_vec (), &fmin, &status, lambda.fortran_vec (), | |
831 redcosts.fortran_vec (), &time, &mem); | |
832 | |
833 octave_scalar_map extra; | |
834 | |
835 if (! isMIP) | |
836 { | |
837 extra.assign ("lambda", lambda); | |
838 extra.assign ("redcosts", redcosts); | |
839 } | |
840 | |
841 extra.assign ("time", time); | |
842 extra.assign ("mem", mem); | |
843 | |
844 retval(3) = extra; | |
845 retval(2) = status; | |
846 retval(1) = fmin; | |
847 retval(0) = xmin; | |
848 | |
849 #else | |
850 | |
851 gripe_not_supported ("glpk"); | |
852 | |
853 #endif | |
854 | |
855 return retval; | |
856 } | |
857 | |
858 /* | |
859 ## No test needed for internal helper function. | |
860 %!assert (1) | |
861 */ |