Mercurial > octave
comparison libinterp/dldfcn/__glpk__.cc @ 21090:93d294511277
don't use setjmp/longjmp to handle error in glpk
* __glpk__.cc (glpk, F__glpk__): Don't use setjmp/longjmp for
non-local exit from glpk. Eliminate volatile from local variable
declarations.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 15 Jan 2016 15:13:28 -0500 |
parents | 4484384a2959 |
children | 72eefc36c6b7 |
comparison
equal
deleted
inserted
replaced
21089:2d7f658daa58 | 21090:93d294511277 |
---|---|
24 #ifdef HAVE_CONFIG_H | 24 #ifdef HAVE_CONFIG_H |
25 #include <config.h> | 25 #include <config.h> |
26 #endif | 26 #endif |
27 | 27 |
28 #include <cfloat> | 28 #include <cfloat> |
29 #include <csetjmp> | |
30 #include <ctime> | 29 #include <ctime> |
31 | 30 |
32 #include "lo-ieee.h" | 31 #include "lo-ieee.h" |
33 | 32 |
34 #include "defun-dld.h" | 33 #include "defun-dld.h" |
69 double objul; | 68 double objul; |
70 double tolint; | 69 double tolint; |
71 double tolobj; | 70 double tolobj; |
72 }; | 71 }; |
73 | 72 |
74 static jmp_buf mark; // Address for long jump to jump to | |
75 | |
76 int | 73 int |
77 glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn, | 74 glpk (int sense, int n, int m, double *c, int nz, int *rn, int *cn, |
78 double *a, double *b, char *ctype, int *freeLB, double *lb, | 75 double *a, double *b, char *ctype, int *freeLB, double *lb, |
79 int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, | 76 int *freeUB, double *ub, int *vartype, int isMIP, int lpsolver, |
80 int save_pb, int scale, const control_params *par, | 77 int save_pb, int scale, const control_params *par, |
166 glp_load_matrix (lp, nz, rn, cn, a); | 163 glp_load_matrix (lp, nz, rn, cn, a); |
167 | 164 |
168 if (save_pb) | 165 if (save_pb) |
169 { | 166 { |
170 static char tmp[] = "outpb.lp"; | 167 static char tmp[] = "outpb.lp"; |
171 if (glp_write_lp (lp, NULL, tmp) != 0) | 168 if (glp_write_lp (lp, 0, tmp) != 0) |
172 { | 169 error ("__glpk__: unable to write problem"); |
173 // FIXME: This doesn't work anymore now that error does not return. | |
174 // Should longjmp just be deleted? | |
175 error ("__glpk__: unable to write problem"); | |
176 longjmp (mark, -1); | |
177 } | |
178 } | 170 } |
179 | 171 |
180 // scale the problem data | 172 // scale the problem data |
181 if (! par->presol || lpsolver != 1) | 173 if (! par->presol || lpsolver != 1) |
182 glp_scale_prob (lp, scale); | 174 glp_scale_prob (lp, scale); |
340 // FIXME: Should we even need checking for an internal function? | 332 // FIXME: Should we even need checking for an internal function? |
341 if (args.length () != 9) | 333 if (args.length () != 9) |
342 print_usage (); | 334 print_usage (); |
343 | 335 |
344 // 1nd Input. A column array containing the objective function coefficients. | 336 // 1nd Input. A column array containing the objective function coefficients. |
345 volatile int mrowsc = args(0).rows (); | 337 int mrowsc = args(0).rows (); |
346 | 338 |
347 Matrix C = args(0).xmatrix_value ("__glpk__: invalid value of C"); | 339 Matrix C = args(0).xmatrix_value ("__glpk__: invalid value of C"); |
348 | 340 |
349 double *c = C.fortran_vec (); | 341 double *c = C.fortran_vec (); |
350 Array<int> rn; | 342 Array<int> rn; |
351 Array<int> cn; | 343 Array<int> cn; |
352 ColumnVector a; | 344 ColumnVector a; |
353 volatile int mrowsA; | 345 int mrowsA; |
354 volatile int nz = 0; | 346 int nz = 0; |
355 | 347 |
356 // 2nd Input. A matrix containing the constraints coefficients. | 348 // 2nd Input. A matrix containing the constraints coefficients. |
357 // If matrix A is NOT a sparse matrix | 349 // If matrix A is NOT a sparse matrix |
358 if (args(1).is_sparse_type ()) | 350 if (args(1).is_sparse_type ()) |
359 { | 351 { |
460 | 452 |
461 // 7th Input. A column array containing the types of the variables. | 453 // 7th Input. A column array containing the types of the variables. |
462 charMatrix VTYPE = args(6).char_matrix_value ("__glpk__: invalid value of VARTYPE"); | 454 charMatrix VTYPE = args(6).char_matrix_value ("__glpk__: invalid value of VARTYPE"); |
463 | 455 |
464 Array<int> vartype (dim_vector (mrowsc, 1)); | 456 Array<int> vartype (dim_vector (mrowsc, 1)); |
465 volatile int isMIP = 0; | 457 int isMIP = 0; |
466 for (int i = 0; i < mrowsc ; i++) | 458 for (int i = 0; i < mrowsc ; i++) |
467 { | 459 { |
468 if (VTYPE(i,0) == 'I') | 460 if (VTYPE(i,0) == 'I') |
469 { | 461 { |
470 isMIP = 1; | 462 isMIP = 1; |
473 else | 465 else |
474 vartype(i) = GLP_CV; | 466 vartype(i) = GLP_CV; |
475 } | 467 } |
476 | 468 |
477 // 8th Input. Sense of optimization. | 469 // 8th Input. Sense of optimization. |
478 volatile int sense; | 470 int sense; |
479 double SENSE = args(7).scalar_value ("__glpk__: invalid value of SENSE"); | 471 double SENSE = args(7).xscalar_value ("__glpk__: invalid value of SENSE"); |
480 | 472 |
481 if (SENSE >= 0) | 473 if (SENSE >= 0) |
482 sense = 1; | 474 sense = 1; |
483 else | 475 else |
484 sense = -1; | 476 sense = -1; |
495 OCTAVE_GLPK_GET_INT_PARAM ("msglev", par.msglev); | 487 OCTAVE_GLPK_GET_INT_PARAM ("msglev", par.msglev); |
496 if (par.msglev < 0 || par.msglev > 3) | 488 if (par.msglev < 0 || par.msglev > 3) |
497 error ("__glpk__: PARAM.msglev must be 0 (no output) or 1 (error and warning messages only [default]) or 2 (normal output) or 3 (full output)"); | 489 error ("__glpk__: PARAM.msglev must be 0 (no output) or 1 (error and warning messages only [default]) or 2 (normal output) or 3 (full output)"); |
498 | 490 |
499 // scaling option | 491 // scaling option |
500 volatile int scale = 16; | 492 int scale = 16; |
501 OCTAVE_GLPK_GET_INT_PARAM ("scale", scale); | 493 OCTAVE_GLPK_GET_INT_PARAM ("scale", scale); |
502 if (scale < 0 || scale > 128) | 494 if (scale < 0 || scale > 128) |
503 error ("__glpk__: PARAM.scale must either be 128 (automatic selection of scaling options), or a bitwise or of: 1 (geometric mean scaling), 16 (equilibration scaling), 32 (round scale factors to power of two), 64 (skip if problem is well scaled"); | 495 error ("__glpk__: PARAM.scale must either be 128 (automatic selection of scaling options), or a bitwise or of: 1 (geometric mean scaling), 16 (equilibration scaling), 32 (round scale factors to power of two), 64 (skip if problem is well scaled"); |
504 | 496 |
505 // Dual simplex option | 497 // Dual simplex option |
539 OCTAVE_GLPK_GET_INT_PARAM ("presol", par.presol); | 531 OCTAVE_GLPK_GET_INT_PARAM ("presol", par.presol); |
540 if (par.presol < 0 || par.presol > 1) | 532 if (par.presol < 0 || par.presol > 1) |
541 error ("__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])"); | 533 error ("__glpk__: PARAM.presol must be 0 (do NOT use LP presolver) or 1 (use LP presolver [default])"); |
542 | 534 |
543 // LPsolver option | 535 // LPsolver option |
544 volatile int lpsolver = 1; | 536 int lpsolver = 1; |
545 OCTAVE_GLPK_GET_INT_PARAM ("lpsolver", lpsolver); | 537 OCTAVE_GLPK_GET_INT_PARAM ("lpsolver", lpsolver); |
546 if (lpsolver < 1 || lpsolver > 2) | 538 if (lpsolver < 1 || lpsolver > 2) |
547 error ("__glpk__: PARAM.lpsolver must be 1 (simplex method) or 2 (interior point method)"); | 539 error ("__glpk__: PARAM.lpsolver must be 1 (simplex method) or 2 (interior point method)"); |
548 | 540 |
549 // Ratio test option | 541 // Ratio test option |
557 | 549 |
558 par.outdly = 0; | 550 par.outdly = 0; |
559 OCTAVE_GLPK_GET_INT_PARAM ("outdly", par.outdly); | 551 OCTAVE_GLPK_GET_INT_PARAM ("outdly", par.outdly); |
560 | 552 |
561 // Save option | 553 // Save option |
562 volatile int save_pb = 0; | 554 int save_pb = 0; |
563 OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb); | 555 OCTAVE_GLPK_GET_INT_PARAM ("save", save_pb); |
564 save_pb = save_pb != 0; | 556 save_pb = save_pb != 0; |
565 | 557 |
566 // Real parameters | 558 // Real parameters |
567 | 559 |
597 double fmin = octave_NA; | 589 double fmin = octave_NA; |
598 ColumnVector lambda (mrowsA, octave_NA); | 590 ColumnVector lambda (mrowsA, octave_NA); |
599 ColumnVector redcosts (mrowsc, octave_NA); | 591 ColumnVector redcosts (mrowsc, octave_NA); |
600 double time; | 592 double time; |
601 int status; | 593 int status; |
602 volatile int errnum = 0; | 594 |
603 | 595 int errnum = glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (), |
604 int jmpret = setjmp (mark); | 596 cn.fortran_vec (), a.fortran_vec (), b, ctype, |
605 | 597 freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub, |
606 if (jmpret == 0) | 598 vartype.fortran_vec (), isMIP, lpsolver, save_pb, scale, |
607 errnum = glpk (sense, mrowsc, mrowsA, c, nz, rn.fortran_vec (), | 599 &par, xmin.fortran_vec (), &fmin, &status, |
608 cn.fortran_vec (), a.fortran_vec (), b, ctype, | 600 lambda.fortran_vec (), redcosts.fortran_vec (), &time); |
609 freeLB.fortran_vec (), lb, freeUB.fortran_vec (), ub, | |
610 vartype.fortran_vec (), isMIP, lpsolver, save_pb, scale, | |
611 &par, xmin.fortran_vec (), &fmin, &status, | |
612 lambda.fortran_vec (), redcosts.fortran_vec (), &time); | |
613 | 601 |
614 octave_scalar_map extra; | 602 octave_scalar_map extra; |
615 | 603 |
616 if (! isMIP) | 604 if (! isMIP) |
617 { | 605 { |